unique index with doctrine mongodb odm - mongodb

i'm doing a registration system for my site and want to prevent duplicate registrations with the same email address.
the declaration of the user class looks like this:
/**
* #Document
*/
class User extends BaseEntity
{
private
/**
* #Id
*/
$id,
/**
* #String #Index(unique=true)
*/
$email
;
}
but whenever i save a user with the same email, no exception is raised and i get a duplicate.
i found somewhere that i need to do $documentManager->flush(array('safe'=>true)); but that doesn't help.
How can I achieve what i need? Thanks

I had a similar problem. The index is not being created by Doctrine as you can see by typing the following in the mongo console:
db.system.indexes.find()
I had to create my index directly in mongo per these instructions. After that duplicates won't be created.
However Symfony2/Doctrine doesn't seem to throw any exceptions, the insert just fails silently. Mongodb DOES alert you of the failed insert if you do it directly in the console.
--edit: An exception is thrown when array('safe'=>true) is used as a parameter to flush() as per the original post.

Related

Auto generating a String non-primary key value using jpa

Kindly help me to find out a solution to my problem.
I have a property of type String in my entity which is not primary key.
This would act as system generated unique profile id for users in my project.
I want to auto generate this value like a random string of particular size.
Could you please help me to arrive at a solution.
I have tried the #Generator and custom id generator class. but still null is getting inserted to the field in db.
I am using maria db.
Hi you can use the hibernate events.
#PostPersist Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed.
Starting with Java 5, the UUID class provides a simple means for generating unique ids. The identifiers generated by UUID are actually universally unique identifiers.
Please follow the sample example.
public class TestModel {
#Column("column_name")
private String uid;
//setter and getter for uid
#PrePersist
protected void onCreate() {
// set the uid
setUid(java.util.UUID.randomUUID());
}
}
Please find the below link for more information on #PrePersist.
https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/listeners.html

How to use two collections to authenticate zfcuser?

I use Doctrine and MongoDB ODM modules at my zf2 application. ZfcUser is used for authorization.
Is there a way to use two collections, say users and clients to authenticate via zfcuser+doctrine? I am curious, if there is a way to combine two mongo collections into one to use combined for authentication?
You do not need to merge the users into one collection as you can have multiple 'authentication adapters' (see ZfcUser\Authentication\Adapter\Db for an example)
These are defined within global config file: zfcuser.global.php
Each of my adapters are run in order of priority until one returns a successful authentication result.
For example; I have the following configuration for Users and Candidates entities.
/**
* Authentication Adapters
*
* Specify the adapters that will be used to try and authenticate the user
*
* Default value: array containing 'ZfcUser\Authentication\Adapter\Db' with priority 100
* Accepted values: array containing services that implement 'ZfcUser\Authentication\Adapter\ChainableAdapter'
*/
'auth_adapters' => array(
50 => 'JobboardCandidate\Authentication\Adapter\CandidateDatabaseAdapter',
75 => 'JobboardUser\Authentication\Adapter\UserDatabaseAdapter',
//100 => 'ZfcUser\Authentication\Adapter\Db', [this is the default]
),
As I understand from your question you want to get one collection with two different document types so that you can use this collection for authentication.
If you use doctrine Inheritance mapping you can have two different classes and resolve them in one collection.
In this case your Client class would extend your User class. If you would use the findAll method in your UserRepository you would get both the clients and the users in one Collection
This will help you achieve what you want:
<?php
namespace MyProject\Model;
/**
* #Document
* #InheritanceType("SINGLE_COLLECTION")
* #DiscriminatorField(name="discriminator", type="string")
* #DiscriminatorMap({"user" = "User", "client" = "Client"})
*/
class User
{
// ...
}
/**
* #Document
*/
class Client extends User
{
// ...
}
And then
$userRepository->findAll();
Read more on inheritance mapping here in the Doctrine documentation

jpa repository save method returns different id from the one inserted into database

I'm using spring data (jpaRepository) + Oracle 11g Database.
Here's the code of my JUnit test:
#Test
public void testAjoutUtilisateur() {
Utilisateur utilisateur = new Utilisateur();
(...)
utilisateur=repository.save(utilisateur);
Utilisateur dbutilisateur = repository.findOne(utilisateur.getIdutilisateur());
assertNotNull(dbutilisateur);
When I debug I find that "utilisateur" object returned by repository.save method has an id like "2100" while the corresponding inserted line in the database have an id like "43".
I have an Oracle database with a sequence and a trigger to have the auto incremented property for the id for my "Utilisateur" table.
Here is the id definition in my Utilisateur entity:
#Entity
#NamedQuery(name="Utilisateur.findAll", query="SELECT u FROM Utilisateur u")
#SequenceGenerator(sequenceName="ID_UTILISATEUR_SEQ", name="ID_UTILISATEUR_SEQ")
public class Utilisateur implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ID_UTILISATEUR_SEQ")
private Long idutilisateur;
Where is the problem? Is it within the save method?
Thank you.
Edit:
I figured out that the problem was already solved by the solution of #jhadesdev and the data lines I was talking about were inserted when the triggers were actives.
Finally, I have to mention that by default the JUnit test seems to not insert data in the database (it inserts then rollback). In order to invalidate this behaviour we have to specify the #TransactionConfiguration(defaultRollback=false) annotation in the test class.
For example (in my case):
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:context/dao-context.xml" })
#TransactionConfiguration(defaultRollback=false)
#Transactional
public class UtilisateurRepositoryTest {
Hope it can help someone.
The problem is that two separate mechanisms are in place to generate the key:
one at Hibernate level which is to call a sequence and use the value to populate an Id column and send it to the database as the insert key
and another mechanism at the database that Hibernate does not know about: the column is incremented via a trigger.
Hibernate thinks that the insert was made with the value of the sequence, but in the database something else occurred. The simplest solution would probably be to remove the trigger mechanism, and let Hibernate populate the key based on the sequence only.

Symfony2 forms embed mongodb document into sql entity

I need little help :). Here is the situation. I am using symfony2 + FOSUserBundle, I made my forms custom, so far so good. I have User registration with user information in the custom registration form (like first name, last name, birth date etc). Now I decided that it will be more practical to make the user info to be stored in mongodb as document (as I probably will add more information to users later). I built the user info form, and successfully embedded it to the user form. Now the problem is that I cannot set Document object inside Entity object - symfony tells me that the object must be an Entity.
/**
* Acme\UserBundle\Entity\User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User extends BaseUser
{
/**
* #Assert\Type(type="Acme\UserBundle\Document\UserInfo")
*/
protected $userinfo;
I want to ask, what is the proper way to do this ? Sure I can get the needed information form the request as an array and fill in the user info object ... but it looks ugly and wrong :) so how it must be done ? Thanks.
I assume you extends the entity class
FOS\UserBundle\Entity\User
there is a document class provided by the bundle
FOS\UserBundle\Document\User
You could extends this one

same password for multi-users in zend

I have the following scenario in zend framework:
Data
Table of students
Table of classes, which contain many students each.
Table of assignments, each of which is assigned to a class and given a password
I want students to be able to access an assignment given that assignment's id and shared password, but for the application to note which student signed in to the assignment. Zend_Auth however expects one table to contain both the username and the password, but in my situation the username is in the students table, and the password is in the assignments table.
Can anyone suggest a good way of handling the student login where they can all share one password. A way to authenticate with just a username and no password would work, as then I could do the password check in a separate conditional.
I think your best bet would really be to just write your own adapter. Something like this would most likely work:
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
protected $_username;
protected $_password;
protected $_assignment_id;
/**
* Sets username, password, and assignemnt ID for authentication
*
* #return void
*/
public function __construct($username,$password,$assignment_id)
{
$this->_username = $username;
$this->_password = $password;
$this->_assignment_id = $assignment_id;
}
/**
* Performs an authentication attempt
*
* #throws Zend_Auth_Adapter_Exception If authentication cannot
* be performed
* #return Zend_Auth_Result
*/
public function authenticate()
{
// logic here to check everything out and erturn a new Zend_Auth_Result
}
}
Shared passwords are a really bad idea. If you share the password, then another student need only learn an id -- typically not a highly secured piece of information -- to access the resource as the other student. A better solution would be to use a role to control access to assignments and put the students who need access to the assignment in the role. This way each student can still have access to the assignment and retain their own id/password pair. See the Zend documentation for information on roles and how to use them.