-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Help!: Noob Question about hibernate mapping
PostPosted: Fri Jun 01, 2007 11:56 pm 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
Hello experts,

I just downloade myeclipse to test hibernate mapping.

Created two simple table in mysql and did reverse engineering.

Let me type the tabel info.

Mysql dump for users table.

/*
MySQL Data Transfer
Source Host: localhost
Source Database: test
Target Host: localhost
Target Database: test
Date: 5/30/2007 11:39:32 PM
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
CREATE TABLE `users` (
`uid` int(11) NOT NULL,
`age` int(11) default NULL,
`firstname` varchar(20) default NULL,
`lastname` varchar(20) default NULL,
PRIMARY KEY (`uid`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `users` VALUES ('1', '30', 'Bruce", 'Lee');
INSERT INTO `users` VALUES ('2', '100', 'John ', 'Wayne');
INSERT INTO `users` VALUES ('3', '33', 'Frank', 'Wong');

Mysql dumb for users_emails

/*
MySQL Data Transfer
Source Host: localhost
Source Database: test
Target Host: localhost
Target Database: test
Date: 5/30/2007 11:39:43 PM
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users_emails
-- ----------------------------
CREATE TABLE `users_emails` (
`id` int(11) NOT NULL,
`user_uid` int(11) NOT NULL,
`email` varchar(30) default NULL,
PRIMARY KEY (`id`,`user_uid`),
KEY `user_uid` (`user_uid`),
CONSTRAINT `users_emails_ibfk_1` FOREIGN KEY (`user_uid`) REFERENCES `users` (`uid`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `users_emails` VALUES ('1', '1', 'johnwayne@hotmail.com');

================================================================


I used reverse engineering on these tables and created POJOS.

In usersemail table id and users id are composite keys. In composite keys situation i had assign primary keys for useremail table.

My problem is when i add email entry to users table by adding useremail object to users , can i insert the data into usersemail table?.

Atpresent i had to explicit save on useremails object. I want user object recognize any useremail object added to its set automatically.

Can someone help me with these?.

My crap code:

private void addEmail(Integer userId, String email) {
try {
//Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();

Users user = (Users) session.load(Users.class, userId);
UsersEmailsId myId=new UsersEmailsId(new Integer(1),user.getUid());
// UsersEmails emails = (UsersEmails) session.load(UsersEmails.class, myId);

UsersEmails emails = new UsersEmails(myId,user,email);


user.getUsersEmailses().add(emails);
//session.save(emails);

tx.commit();
hsqlCleanup(session);
//HibernateUtil.closeSession();
tearDown();
} catch (HibernateException e) {
throw new RuntimeException(e);
}
catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}

Above code does not insert without next line i commented ( session.save(emails); )

Here is my useremails.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="EventOrganizer.UsersEmails" table="users_emails" catalog="test">
<composite-id name="id" class="EventOrganizer.UsersEmailsId">
<key-property name="id" type="java.lang.Integer">
<column name="id" />
</key-property>
<key-property name="userUid" type="java.lang.Integer">
<column name="user_uid" />
</key-property>
</composite-id>
<many-to-one name="users" class="EventOrganizer.Users" update="false" insert="false" fetch="select">
<column name="user_uid" not-null="true" />
</many-to-one>
<property name="email" type="java.lang.String">
<column name="email" length="30" />
</property>
</class>
</hibernate-mapping>


Please email me if you can help me with these ?,

Also if any of experts have do's and don'ts for hibernate mapping rules?.

Your help is very much appreciated. Please email me at pokerking400@hotmail.com or respond here.

Thanks
alexk


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 10:43 am 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
Just modified the table to make it simpler to discuss the main issue i have. Remove compositekeys (redundant in this issue).

I have two Tables in mysql. USERS and USERS_EMAILS.

Users - sql dump:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users
-- ----------------------------
CREATE TABLE `users` (
`uid` int(11) NOT NULL,
`age` int(11) default NULL,
`firstname` varchar(20) default NULL,
`lastname` varchar(20) default NULL,
PRIMARY KEY (`uid`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `users` VALUES ('1', '40', 'Tom', 'Hanks');
INSERT INTO `users` VALUES ('2', '100', 'John ', 'Wayne');
INSERT INTO `users` VALUES ('3', '33', 'Frank', 'Wong');

Users_emails - :sql dump

/*
MySQL Data Transfer
Source Host: localhost
Source Database: test
Target Host: localhost
Target Database: test
Date: 6/2/2007 10:28:08 AM
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for users_emails
-- ----------------------------
CREATE TABLE `users_emails` (
`id` int(11) NOT NULL,
`user_uid` int(11) NOT NULL,
`email` varchar(30) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `user_uid` (`user_uid`),
CONSTRAINT `users_emails_ibfk_1` FOREIGN KEY (`user_uid`) REFERENCES `users` (`uid`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records
-- ----------------------------

Created POJOS using myeclipse tools.

USERS.HBM.XML
=============

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="EventOrganizer.Users" table="users" catalog="test">
<id name="uid" type="java.lang.Integer">
<column name="uid" />
<generator class="increment" />
</id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="firstname" type="java.lang.String">
<column name="firstname" length="20" />
</property>
<property name="lastname" type="java.lang.String">
<column name="lastname" length="20" />
</property>
<set name="eventses" table="favourite_events" catalog="test">
<key>
<column name="users_uid" not-null="true" />
</key>
<many-to-many entity-name="EventOrganizer.Events">
<column name="events_uid" not-null="true" />
</many-to-many>
</set>
<set name="usersEmailses" inverse="true">
<key>
<column name="user_uid" not-null="true" />
</key>
<one-to-many class="EventOrganizer.UsersEmails" />
</set>
</class>
</hibernate-mapping>


UsersEMails.hbm.xml
================

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="EventOrganizer.UsersEmails" table="users_emails" catalog="test">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="increment" />
</id>
<many-to-one name="users" class="EventOrganizer.Users" fetch="select">
<column name="user_uid" not-null="true" />
</many-to-one>
<property name="email" type="java.lang.String">
<column name="email" length="30" />
</property>
</class>
</hibernate-mapping>

===================================

Java code :

private void addEmail(Integer userId, String email) {
try {
Transaction tx = session.beginTransaction();
Users user = (Users) session.load(Users.class, userId);
UsersEmails emails = new UsersEmails(user,email);
user.getUsersEmailses().add(emails);
// session.save(emails);

tx.commit();
hsqlCleanup(session);
tearDown();
} catch (HibernateException e) {
throw new RuntimeException(e);
}
catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}


My problem is i have to save emails by explisit call to session by save(emails).

I want this to be saved automatically by hibernate detecting change in users email set.

Can someone help me with these?.

Thanks
alexk


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 3:13 pm 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
Try with:
Code:
<one-to-many class="EventOrganizer.UsersEmails" cascade="persist" />

Or with:
Code:
<one-to-many class="EventOrganizer.UsersEmails" cascade="all,delete-orphan" />

And read chapter 10.11. Transitive persistence from the Hibernate reference.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 02, 2007 8:51 pm 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
yes it solved one problem not all.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="EventOrganizer.Users" table="users" catalog="test">
<id name="uid" type="java.lang.Integer">
<column name="uid" />
<generator class="increment" />
</id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="firstname" type="java.lang.String">
<column name="firstname" length="20" />
</property>
<property name="lastname" type="java.lang.String">
<column name="lastname" length="20" />
</property>
<set name="eventses" table="favourite_events" catalog="test">
<key>
<column name="users_uid" not-null="true" />
</key>
<many-to-many entity-name="EventOrganizer.Events">
<column name="events_uid" not-null="true" />
</many-to-many>
</set>
<set name="usersEmailses" inverse="true" cascade="all, delete-orphan" lazy="true">
<key>
<column name="user_uid" not-null="true" />
</key>
<one-to-many class="EventOrganizer.UsersEmails"/>
</set>
</class>
</hibernate-mapping>

1. I can add Email without explicit session.save.
2. if i delete user , it also deletes all emails associated with that user.

Now my problem is how do i delete one email belong to that user?

private void deleteEmail(Integer userId, String email) {
try {
Transaction tx = session.beginTransaction();
Users user = (Users) session.load(Users.class, userId);
UsersEmails emails = new UsersEmails(user,email);
user.getUsersEmailses().remove(emails);
tx.commit();
hsqlCleanup(session);
tearDown();
} catch (HibernateException e) {
throw new RuntimeException(e);
}
catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}

Above code is not working. Again i have to do explict save or update on individual email.

I think that is the only way because every user is associated with multiple emails. unless if you know better way.

Let me know.

Thanks
alexk


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 6:42 am 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
Have you correctly overridden the equals() method of UsersEmails class?

If not, it implies that emails is a different object of any other UserEmails object (though it have the same id) in the code:
Code:
UsersEmails emails = new UsersEmails(user,email);
user.getUsersEmailses().remove(emails);

You aren't removing anything from UsersEmailses Set. Test their number of elements after and before.

Do you get it?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jun 03, 2007 11:53 pm 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
hi,

Thanks for your reply.

I could not remove UserEmail from emailset even with equals and hashcode methods.

Downloading java source code to see what is happening in set.remove called.
it calls my useremails.hashcode method then it fails.

So i checked the code with emailset.clear by clearing the whole set to see whether it was removing all rows.

YESSS. it does. So the problem is with my remove for each email.

So far i have done ,

Add , delete. Update may not be a problem if delete works.

So now i have become expert of "One to many , Many to one" relationship.

Next project is many to many (bidirectional relationship).

Then i have to write my own tutorial to help other noobs.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 04, 2007 1:19 am 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
Implemented equals and hashcode as follows

public boolean equals(Object o) {
String email=getEmail();
if (this == o) return true;
if (o == null || !(o instanceof UsersEmails))
return false;

UsersEmails other = (UsersEmails)o;

if (email == other.getEmail()) return true;
if (email == null) return false;

// equivalence by id
return email.equals(other.getEmail());
}

public int hashCode() {
String email=getEmail();
if (email != null) {
return email.hashCode();
} else {
return super.hashCode();
}
}


It works now.

Now i need to find a way to generate this hashcode and equals for all classes. Then i can customize it later.

Can you give me all different relationship possible in hibernate?.

Many to one
One to Many
Many to Many (bidirectional)

Anything else?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 04, 2007 2:23 am 
Newbie

Joined: Thu Apr 21, 2005 6:04 am
Posts: 8
Can you explain Inverse="true" ?.

http://simoes.org/docs/hibernate-2.1/155.html

I just want to know at what situation inverse="true" should be used and what is the difference between cascade and inverse?.

Thanks


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.