-->
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.  [ 12 posts ] 
Author Message
 Post subject: Insert on Parent only on a one-to-many relation
PostPosted: Wed Feb 04, 2004 7:24 am 
Newbie

Joined: Wed Jan 28, 2004 7:43 am
Posts: 1
Hi,

Is there any way to insert a row in the parent table alone using hibernate.

My case is like this

A department table is related to an employee table in one-to many fashion. But while trying to insert a row in department, i am force to add a set of employees also.The ddl used to create the schema are as follows

create table department (dept_id varchar(15) primary key,
dept_name varchar(50),
dept_location varchar(50));

create table employee (emp_id number(10) primary key,
emp_name varchar(50),
dept_id varchar(15),
foreign key (dept_id) references department(dept_id));


I used middlegen to create the mapping files they are as follows

Department.hbl.xml-----------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin

http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->

<class
name="com.roche.dal.Department"
table="DEPARTMENT"
>

<id
name="deptId"
type="java.lang.String"
column="DEPT_ID"
>
<generator class="assigned" />
</id>

<property
name="deptName"
type="java.lang.String"
column="DEPT_NAME"
length="50"
/>
<property
name="deptLocation"
type="java.lang.String"
column="DEPT_LOCATION"
length="50"
/>

<!-- associations -->
<!-- bi-directional one-to-many association to Employee -->

<set
name="employees"
lazy="true"
inverse="false"
cascade="delete"
>
<key>
<column name="DEPT_ID" />
</key>
<one-to-many
class="com.roche.dal.Employee"

/>
</set>

</class>
</hibernate-mapping>

employee.hbm.xml--------------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin

http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->

<class
name="com.roche.dal.Employee"
table="EMPLOYEE"
>

<id
name="empId"
type="java.lang.String"
column="EMP_ID"
>
<generator class="assigned" />
</id>

<property
name="empName"
type="java.lang.String"
column="EMP_NAME"
length="50"
/>

<!-- associations -->
<!-- bi-directional many-to-one association to Department -->


<many-to-one
name="department"
class="com.roche.dal.Department"
not-null="true"
>
<column name="DEPT_ID" />
</many-to-one>


<!-- bi-directional one-to-one association to EmployeeSecurityData -->
<one-to-one
name="employeeSecurityData"
class="com.roche.dal.EmployeeSecurityData"
outer-join="auto"
/>
<!-- bi-directional one-to-many association to DocumentReviewData -->
<set
name="documentReviewDatas"
lazy="true"
inverse="true"
>
<key>
<column name="EMP_ID" />
</key>
<one-to-many
class="com.roche.dal.DocumentReviewData"
/>
</set>
<!-- bi-directional many-to-many association to DocumentData -->
<set
name="documentDatas"
lazy="true"
table="DOCUMENT_REVIEW_DATA"
>
<key>
<column name="EMP_ID" />
</key>
<many-to-many
class="com.roche.dal.DocumentData"
>
<column name="DOC_ID" />
</many-to-many>
</set>

</class>
</hibernate-mapping>


and my generated Department class is

import java.io.Serializable;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/** @author Hibernate CodeGenerator */
public class Department implements Serializable {

/** identifier field */
private String deptId;

/** nullable persistent field */
private String deptName;

/** nullable persistent field */
private String deptLocation;

/** persistent field */
private Set employees;

/** full constructor */
public Department(String deptId, String deptName, String deptLocation, Set employees) {
this.deptId = deptId;
this.deptName = deptName;
this.deptLocation = deptLocation;
this.employees = employees;
}

/** default constructor */
public Department() {
}

/** minimal constructor */
public Department(String deptId, Set employees) {
this.deptId = deptId;
this.employees = employees;
}

public String getDeptId() {
return this.deptId;
}

public void setDeptId(String deptId) {
this.deptId = deptId;
}

public String getDeptName() {
return this.deptName;
}

public void setDeptName(String deptName) {
this.deptName = deptName;
}

public String getDeptLocation() {
return this.deptLocation;
}

public void setDeptLocation(String deptLocation) {
this.deptLocation = deptLocation;
}

public Set getEmployees() {
return this.employees;
}

public void setEmployees(Set employees) {
this.employees = employees;
}

public String toString() {
return new ToStringBuilder(this)
.append("deptId", getDeptId())
.toString();
}

public boolean equals(Object other) {
if ( !(other instanceof Department) ) return false;
Department castOther = (Department) other;
return new EqualsBuilder()
.append(this.getDeptId(), castOther.getDeptId())
.isEquals();
}

public int hashCode() {
return new HashCodeBuilder()
.append(getDeptId())
.toHashCode();
}

}



Since I want to have other tables related to employee, I can add an employee when ever a department is added.

Is there any configuration setting or any parameter in the mapping file so that i can insert to the parent table alone?


Thanks in advance
Deepak


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 04, 2004 10:41 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Well just save a department with an empty Employee Set ...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 04, 2004 3:29 pm 
Newbie

Joined: Sat Nov 15, 2003 4:44 pm
Posts: 6
Location: A Coru
quite the opposite, i'm trying insert a set of child entities 'Boletin' ( Bulletin ) as the same time as i insert a new parent entity 'Usuario' ( User ).

is this possible only save de parent entity ?

.....
session.save( usuario );
.....

i think ( and i could like ) it's possible reading deepak's post but at the moment i haven't it achieved :-(


mapping files and code
-----------------------------------------------------------------

############################ ### Usuario.hbm.xml


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping>
<!--
Created by Middlegen Hibernate plugin

http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->

<class
name="com.cca.database.hibernate.Usuario"
table="usuario"
>

<id
name="codUsuario"
type="java.lang.Long"
column="codUsuario"
>
<generator class="identity" />
</id>

<property
name="nombre"
type="java.lang.String"
column="nombre"
not-null="true"
length="200"
/>

.... more properties ....


<!-- associations -->

... more asociations .....

<!-- bi-directional one-to-many association to Boletin -->
<set
name="boletines"
lazy="true"
inverse="true"
>
<key>
<column name="codUsuario" />
</key>
<one-to-many
class="com.cca.database.hibernate.Boletin"
/>
</set>
... more asociations .....

</class>
</hibernate-mapping>

############################ ### Boletin.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping>
<!--
Created by Middlegen Hibernate plugin

http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->

<class
name="com.cca.database.hibernate.Boletin"
table="boletin"
>

<id
name="codBoletin"
type="java.lang.Long"
column="codBoletin"
>
<generator class="identity" />
</id>

<property
name="fechaBoletin"
type="java.sql.Timestamp"
column="fechaBoletin"
not-null="true"
length="19"
/>

.... more properties ....

<!-- associations -->
<!-- bi-directional many-to-one association to Usuario -->
<many-to-one
name="usuario"
class="com.cca.database.hibernate.Usuario"
not-null="true"
>
<column name="codUsuario" />
</many-to-one>

</class>
</hibernate-mapping>

############################### ### Java Code


... ... ... ...

Set bulletins = new HashSet();

Boletin bulletin1 = new Boletin( new Date(), "bulletin 1" );
bulletins.add( bulletin1 );
Boletin bulletin2 = new Boletin( new Date(), "bulletin 2" );
bulletins.add( bulletin2 );
Boletin bulletin3 = new Boletin( new Date(), "bulletin 3" );
bulletins.add( bulletin3 );

Transaction tx = session.beginTransaction();

Usuario usuario = new Usuario( "new user", ... more params..., bulletins );
session.save( usuario ); // Why the bulletins are not saved ???
tx.commit();

... ... ... ...

############################ ### Output Console

Hibernate: insert into usuario (nombre, apellidos, dniCifPasaporte, edad, sexo, eMail, domicilio, poblacion, cp,

telefono1, telefono2, login, password, personaContacto, codPais, codProvincia, codSector, codPerfil) values (?, ?,

?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()

-----------------------------------------------------------------

What's wrong ???

if this behavior isn't possible i don't know why the parent entity take instances of chil entities
in the contructor


Thanks in advance and sorry for my english !!!

Eduardo.
A Coru


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 04, 2004 3:48 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Ah, you want something like cascade, i suppose. Take a look at http://www.hibernate.org/hib_docs/reference/html/parent-child.html#parent-child-cascades


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 05, 2004 12:38 pm 
Newbie

Joined: Sat Nov 15, 2003 4:44 pm
Posts: 6
Location: A Coru
Thanks for your reply, gloeglm.

... and this has been one step beyond. I've modified 'Usuario.hbm.xml' adding to the set 'boletines' the attribute 'cascade=all' as follows:

############################ ### Usuario.hbm.xml

...............
<!-- bi-directional one-to-many association to Boletin -->
<set
name="boletines"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="codUsuario" />
</key>
<one-to-many
class="com.cca.database.hibernate.Boletin"
/>
</set>
...............

I've modified my code as follows:

############################### ### Java Code
Transaction tx = session.beginTransaction();

Set bulletins = new HashSet();
Usuario user = new Usuario( "new user", ... more params..., bulletins );

Boletin bulletin1 = new Boletin( new Date(), "bulletin1", user );
bulletins.add( bulletin1 ); // i've tried too user.getBulletins().add( bulletin1 )


Boletin bulletin2 = new Boletin( new Date(), "bulletin2", user );
bulletins.add( bulletin2 ); // i've tried too user.getBulletins().add( bulletin2 )


Boletin bulletin3 = new Boletin( new Date(), "bulletin3", user );
bulletins.add( bulletin3 ); // i've tried too user.getBulletins().add( bulletin3 )

session.save( usuario );
tx.commit();

--------------------------------------------------------------------------------

... and now my entity 'User' is persisted but only the entity 'bulletin1' it's too. Why 'bulletin2' and 'bulletin3' are not inserted in the DB ??

in view of i've described above i've modified my code as follows( only to satisfy my cusiosity ):

############################### ### Java Code
Transaction tx = session.beginTransaction();

Set bulletins = new HashSet();
Usuario user = new Usuario( "new user", ... more params..., bulletins );

Boletin bulletin1 = new Boletin( new Date(), "bulletin1", user );
bulletins.add( bulletin1 ); // i've tried too user.getBulletins().add( bulletin1 )
session.saveOrUpdate( user );

Boletin bulletin2 = new Boletin( new Date(), "bulletin2", user );
bulletins.add( bulletin2 ); // i've tried too user.getBulletins().add( bulletin2 )
session.saveOrUpdate( user );

Boletin bulletin3 = new Boletin( new Date(), "bulletin3", user );
bulletins.add( bulletin3 ); // i've tried too user.getBulletins().add( bulletin3 )
session.saveOrUpdate( user );

tx.commit();

--------------------------------------------------------------------------------

... and surprisingly was inserted in the DB, of course, the entity 'user' and the child entities 'bulletin1' and 'bulletin2'. Where is 'bulletin3' ??

i can't understand this behavior !!!



Thanks in advance and sorry for my english !!!

Eduardo.
A Coru


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 05, 2004 5:00 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
What SQL is generated? How does your equals/hashCode look like? Is this really exactly the code you execute?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 06, 2004 8:26 am 
Newbie

Joined: Sat Nov 15, 2003 4:44 pm
Posts: 6
Location: A Coru
Yes gloeglm, this is really exactly the code i execute !! Are you too surpised for the obtained result ??

For my first test ( see reference in my last post ) the output console was as fowolls:

############################ ### Output Console

Hibernate: insert into usuario (nombre, apellidos, dniCifPasaporte, edad, sexo, eMail, domicilio, poblacion, cp, telefono1, telefono2, login, password, personaContacto, codPais, codProvincia, codSector, codPerfil) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()
Hibernate: insert into boletin (fechaBoletin, rutaPdf, codUsuario) values (?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()


For the second test the output console was as fowolls:

############################ ### Output Console

Hibernate: insert into usuario (nombre, apellidos, dniCifPasaporte, edad, sexo, eMail, domicilio, poblacion, cp, telefono1, telefono2, login, password, personaContacto, codPais, codProvincia, codSector, codPerfil) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()
Hibernate: insert into boletin (fechaBoletin, rutaPdf, codUsuario) values (?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()
Hibernate: insert into boletin (fechaBoletin, rutaPdf, codUsuario) values (?, ?, ?)
Hibernate: SELECT LAST_INSERT_ID()

Last, my equals and hashCode methods, generated by Hibernate CodeGenerator:

############################ ### Usuario.java

... ... ...

public boolean equals( Object other ) {
if( ! ( other instanceof Usuario ) ) {
return false;
}
Usuario castOther = ( Usuario )other;
return new EqualsBuilder()
.append( this.getCodUsuario(), castOther.getCodUsuario() )
.isEquals();
}

public int hashCode() {
return new HashCodeBuilder()
.append( getCodUsuario() )
.toHashCode();
}

... ... ...

############################ ### Boletin.java

... ... ...

public boolean equals( Object other ) {
if( ! ( other instanceof Boletin ) ) {
return false;
}
Boletin castOther = ( Boletin )other;
return new EqualsBuilder()
.append( this.getCodBoletin(), castOther.getCodBoletin() )
.isEquals();
}

public int hashCode() {
return new HashCodeBuilder()
.append( getCodBoletin() )
.toHashCode();
}

... ... ...


Curiously, in my second test, you can add the number of instances of 'Boletin' what you want, as follows:

############################### ### Java Code

... ... ...

Boletin bulletin1 = new Boletin( new Date(), "bulletin1", user );
user.getBulletins().add( bulletin1 ) // bulletin 1
session.saveOrUpdate( user );

... ... ...

Boletin bulletinN = new Boletin( new Date(), "bulletinN", user );
user.getBulletins().add( bulletinN ) // bulletin n
session.saveOrUpdate( user );

... ... ...

---------------------------------------------------------------------------

Only the first ans second instances of Boletin are inserted in the DB.


What's happen ??

Thanks.

Eduardo.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 06, 2004 8:39 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Most likely the problem is you insert a lot of elements into a hashSet which all have the same identifier (null) and all have the same hashCode and are all equal. What rather puzzles me is that you do saveOrUpdate() in between .. try calling session.flush() after every saveOrUpdate()


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2004 1:07 pm 
Newbie

Joined: Sat Nov 15, 2003 4:44 pm
Posts: 6
Location: A Coru
all right gloeglm ...

if i call session.flush() after every saveOrUpdate(), the instances of bulletin are inserted in the database, but i would like, and i thought that hibernate worked in other manner.

Don't you think that if a parent entity take a Set of instances of child entities in the constructor, would be logical to persist the child entities in the same moment ( in the same sentence -> session.save( parent ) ) that the parent entity is persisted ?

i'm a new hibernate user and i'm trying to understand the tool's possibilities.

Thank you for your help.

Eduardo.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2004 1:15 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
You can not insert multiple new instances into a set, if your equals method relies on the identifier (they have all null as the id value). Every new entry will replace the old one.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2004 1:16 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
It seems not to be related to Hibernate but to equals/hashcode Java specification. Try to implement a proper equals method http://www.hibernate.org/Documentation/EqualsAndHashCode

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 09, 2004 1:20 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The pattern described at this page is not a good practice! I added a comment...

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 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.