File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Object Relational Mapping and the fly likes hibernate one to many mapping inserts into User table but not in mapped Email table. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "hibernate one to many mapping inserts into User table but not in mapped Email table." Watch "hibernate one to many mapping inserts into User table but not in mapped Email table." New topic
Author

hibernate one to many mapping inserts into User table but not in mapped Email table.

Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
I am implementing one to many relationship. This is for user registration. On trying to save User object (which has a set of email Ids) it gets saved in User table but not in email table.

Below are the two tables:


Below are the mapping files:





Below are the POJOS:

User.java


Email.java


Below is the code that is saving the the User Object (which has list of email ids)




It inserts into User table perfectly. But there is no data inserted in Email table. Please advice.

thanks.


Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello!

Probably you need to add cascade="persist" to tell hibernate persist emailIds collection when persisting User.


True person is moral, false is right!
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
Thanks.I added that cascade="persist",it did not work. The i checked on google and there was an option cascade="all" and it worked. Now on saving the user object it is saving in both the tables:

mysql> select * from user;
+--------+------+----------+----------+--------+------+
| userid | name | username | password | cellno | dob |
+--------+------+----------+----------+--------+------+
| 1 | fsdf | sa | 1111111 | 1111 | 11 |
+--------+------+----------+----------+--------+------+
1 row in set (0.00 sec)

mysql> select * from email;
+---------------+--------+
| emailId | userId |
+---------------+--------+
| abc@yahoo.com | NULL |
| xyz@yahoo.com | NULL |
+---------------+--------+
2 rows in set (0.00 sec)


But now one issue is left that userId in email table is coming null.

thanks.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello Monica!

I read this article. It explains well what are possible values of 'cascade' attribute.
As probably record in email table does not have any sense without corresponding record in user table it is reasonable to set cascade =”all-delete-orphan”. It means if you delete Email instance from emailIds collection corresponding record from email table will be deleted.
I read that it is good practice to maintain both sides of relationship. If User contains Email instance then Email should also contain User instance.
HIbernate maps Email entity to email table. Property emailId is mapped to emailId column and property user is mapped to userId column. If property user in Email instance is null then corresponding userId column in email table is null!
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
thanks. I have a question. Is the table structure correct?I mean this is for user registration. User can have any number of emails. So I have one to many relationship. Now in the Email table what all should I have: I have email Id which is unique, so I assume there is no need for another auto increment variable when emailId is already unique primary key. So in that case should the Email table have only 1 entry that is EmailId and one for UserId? Or userId entry is not required in Email table.there can be only 1 column in email table that is EmailId. I could think of the below structure which may be correct or wrong?Is the below structure correct?

mysql> describe user;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| userid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| username | varchar(255) | YES | | NULL | |
| password | varchar(255) | YES | | NULL | |
| cellno | varchar(255) | YES | | NULL | |
| dob | varchar(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)


mysql> describe email;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| emailId | varchar(255) | NO | PRI | NULL | |
| userId | int(11) | YES | MUL | NULL | |
+---------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)



thanks
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello Monica!

As I read it is easy to implement one-to-many bidirectional association setting many-to-one as owner of relationship by inverse="true".
In this case table email will have column userId that points to primary key of user table. This userId column is foreign key column whereas emailId is primary key in email table. Also you need in email table another column that holds email itself.
I would use collection mapping here. As every email should be unique it is best to use set. And I found tutorial on this here.
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
so you mean to say userId column will come in Email table only in case of one to many Bidirectional and not in case of one to many unidirectional? So in case of one to many unidirectional in Email table we should have only one column that is EmailId?

thanks
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello Monica!

Hibernate maps entity to table. Hibernate maps every property of entity to corresponding column. If property is annotated by @Transient it is not mapped to column.
For database one-to-many means that table on many side has foreign key column that refers to primary key column of table on one side. I wonder what is the difference between unidirectional and bidirectional one-ro-many relationship in database. For database many-to-many is always done with third table(join table).
Hibernate represents these db relationships by Java objects! So in one-to-many relationship entity on one side owns collection of entities of many side. Entity on many side holds single reference to entity on one side. Unidirectional one-to-many on foreign key is not recommended. But unidirectional one-to-many with third table(join table) is recommended.
I myself in my rpoject use bidirectional many-to-one relationship.
The conclusion is to use either unidirectional many-to-one(in this case you don't have collection of emails in user entity but have reference to user in email entity) or unidirectional one-to-many with join table or bidirectional many-to-one with foreign key column in many side.
Balaji Vankadaru
Ranch Hand

Joined: May 31, 2013
Posts: 47
Everything you have done regarding cascade=ALL implementation is cool.

Check one thing.

For fetching the details of email id's you have added email object to the user.

Now to get the details of user based on email.

Why you did not feel of inserting user object to email ??



Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
So my understanding is that since I am having UserId column in Email table it is Bidirectional One to Many. If there is no userId column in Email table (only EmaiId colunn) it will be unidirectional one to many mapping. Please correct me if I am wrong. For some reason UserId is coming blank in Email table.

thanks...
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello Monica!

You have database representation of your data and object-oriented representation. Mapping between database tables and java objects is done by hibernate.
For database bidirectional one-to-many I think you really need only userId foreign key column in Email table. This is in database!
For java objects bidirectional one-to-many I think you really need reference to user in Email object and collection of Email in User object. Both sides have refrences to one another and this is called bidirectional relationship for java objects.
If you want to have userId foreign key column in Email table not empty then provide 'user' reference in Email object.
Code you posted at the beginning clearly says that email objects 'email1' and 'email2' don't have references to user object.
I want to emphasize that Email entity is mapped to email table and Email properties('emailId' and 'user') are mapped to columns in email table('emailId' and 'userId')
The same is with User entity - its properties userId,name,userName,pasword,cellNo,website,birthDate are mapped tp corresponding columns in user table. This mapping is done via annotations or xml elements.
So 'user' reference in Email entity is mapped to 'userId' foreign key column in Email table. If 'user' reference is null then 'userId' column is null. If 'user' reference is pointing to some User object then primary key of this User object(you set it by <id name="userId".../> element) is set as value of foreign key column 'userId' in email table.
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
Thanks.I will try that. Also I am experiencing another issue that whenever I am saving the User object, it is saving into the User and Email tables but it is truncating the previous records. So whenever I save user object, the latest record gets inserted but previous records disappear from the tables.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

It may be that your hibernate configuration has this property
hibernate.hbm2ddl.auto
If it is set to value create it means on every new run your database will be recreated.
I recommend to put it as update means create db if it does not exist and update db if mapping in hbm.xml has changed.
Or you can put it to validate which means mae no changes.
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
Thanks.I removed the complete line and it worked perfectly. You had said I should have emailId (autogenerated) and email in the Email table along with userId. But I have emailId(not autogenerated but it is the email like xyz@gmail.com ) I think there is no need for any autogenerated column for email because emailId itself(xyz@gmail.com ) is unique so why would any other autogenerated number be required for primary key.

thanks.

Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello!

You want to use natural primary key. About this you can read more here.
Extract :
Do only use a natural id, if you are absolutely sure, that the columns included in this id, will never change.

Finally I encourage you to read parts of this book which are available for free.

Really it seems the best to use collection mapping.
Then hibernate will manage email table completely for you.
You will have method

Then you can save,delete,update only User object and email table will be updated ( by hibernate) according to emailIds collection in this User object.
So you must care about content of emailIds collection only but not about saving,updating email objects itself. Email without User has no sense!

I recommend to do some research or better ask on stackoverflow about type of collection to use in collection mapping.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Sorry Monica, I have made a mistake there.
Actually using collection mapping you may get rid of Email entity altogether and have user emails as
Set<String> emailIds=new HashSet<String>();
Hovewer, if you will need more than one string property to represent email (sounds tricky) you may use @Embaddable annotation on your Email entity.
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
Do only use a natural id, if you are absolutely sure, that the columns included in this id, will never change.


But EmaiId would always be unique so in that case it makes sense to make emaiId the primary key but then what would be the use of using autoincrement primary key for this table.
Volodymyr Levytskyi
Ranch Hand

Joined: Mar 29, 2012
Posts: 505
    
    1

Hello Monica!

Read carefully that Extract once more. It tells that natural id column should never change but not only be unique.
Monica. Shiralkar
Ranch Hand

Joined: Jul 07, 2012
Posts: 671
natural id column should never change but not only be unique.


Oh got it so emailId would not be a primary key because emailId might get updated and changed. Actually I read that primary key should be unique nowhere did I read the primary key should not change.
thanks
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: hibernate one to many mapping inserts into User table but not in mapped Email table.