-->
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.  [ 36 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: How to enable lazy initialization for one-to-one
PostPosted: Thu Dec 04, 2003 2:50 pm 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
I have a one-to-one association. I am using Hibernate 2.1. Whenever I get the parent (one-to-one), Hibernate gets also the child (many-to-one). I set outer-join="false" but this did not solve the problem. Is it possible to get the parent, without getting the child, in one-to-one association. If so how?

Thank you,

mota


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 04, 2003 4:00 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
You need to use proxy for child.

http://www.hibernate.org/45.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 04, 2003 5:16 pm 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
I added proxy="className" to the mapping of the child, but I still have eager fetching. Is there anything else I need to do?

mota


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 04, 2003 5:42 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Using proxy for child should be enough.

Could you paste your mapping and code here?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 3:55 pm 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
My mapping files look like this:

<class
name="test.Parent"
table="Parent"
>
<id
name="id"
column="Id"
type="long"
unsaved-value="null"
>
<generator class="seqhilo">
<param name="sequence">parent_sequence</param>
</generator>
</id>
<version
name="version"
type="java.lang.Integer"
column="version"
/>
<property
name="field"
type="string"
update="true"
insert="true"
column="Field"
length="7"
/>
<one-to-one
name="child"
class="test.Child"
cascade="save-update"
outer-join="false"
constrained="false"
property-ref="parent"
/>
</class>

<class
name="test.Child"
table="Child"
>
<id
name="id"
column="Id"
type="long"
unsaved-value="null"
>
<generator class="seqhilo">
<param name="sequence">child_sequence</param>
</generator>
</id>
<version
name="version"
type="java.lang.Integer"
column="version"
/>
<property
name="field"
type="string"
update="true"
insert="true"
column="Field"
length="7"
/>
<many-to-one
name="parent"
class="test.Parent"
cascade="none"
outer-join="false"
update="true"
insert="true"
column="Id"
not-null="true"
unique="true"
/>
</class>

I am using Hibernate 2.1. With this mapping, whenever I get the parent (with session.load(Parent, parentId)), it comes with the child.
If I add proxy="test.Child" to the child's mapping, same as above.
If I use proxy="test.Parent" on the parent's mapping, even the parent is not initialized (no sql is executed by Hibernate).

In my case the parent is also part of a graph, and I need lazy initialization at all levels. Lazy initialization is working fine with one-to-many, many-to-many (lazy=true) and many-to-one (with proxy), but so far not for one-to-one.

What am I missing?


mota


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 4:21 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
How do you determine "it comes with child"? Could you please paste log/output?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 4:38 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Btw, outer-join should be "auto". But I don't think this will make difference...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 4:42 pm 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
dimas wrote:
"How do you determine "it comes with child"? Could you please paste log/output?"


By looking at the sql executed by hibernate:
Hibernate: select parent0_.Id as Id0_, parent0_.version as version0_, parent0_.Field as Field0_ from Parent parent0_ where parent0_.Id=?

Hibernate: select child0_.Id as Id0_, child0_.version as version0_, child0_.Field as Field0_ from Child child0_ where child0_.Id=?

mota


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 6:30 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
I wonder how your mapping works at all. I'm getting

Code:
net.sf.hibernate.MappingException: Repeated column in mapping for class test.Child should be mapped with insert="false" update="false": Id
   at net.sf.hibernate.persister.AbstractEntityPersister.checkColumnDuplication(AbstractEntityPersister.java:935)
   at net.sf.hibernate.persister.EntityPersister.<init>(EntityPersister.java:833)
   at net.sf.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:41)
   at net.sf.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:136)
   at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:720)
   at Test.main(Test.java:25)



Hibernate 2.1 beta 6


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 6:47 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Anyway, your problem caused by outer-join="false". Remove it or set to "auto" and child will not be loaded. I wasn't sure about that, but I checked and it works that way.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 1:04 am 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
dimas wrote:
" I wonder how your mapping works at all. I'm getting "


The mapping I posted was a simulation of my case, and I haven't run it as is. For the one-to-one, the child holds the foreign key pointing to the parent's primary. The exception is caused by the foreign key in the child having the same name as the child's primary key (Id). In my test, changing outer-join from "flase" to "auto" did not have any impact on lazy initialization.

mota


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 8:25 am 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
Look, it is difficult to help you if you proide only a "simulation" code.

I think you need either:
1. paste the REAL code/mapping which does not work
2. reproduce exactly the same problem with your "simulation" code. Because latter works fine with outer-join="auto", I consider there are some other problem with your real code.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 9:04 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
This is a FAQ
http://www.hibernate.org/117.html#A13

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 5:12 pm 
Regular
Regular

Joined: Wed Nov 05, 2003 10:57 pm
Posts: 96
Below is the code and mappings I use in my:

Persistent objects:

package test;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* @hibernate.class
* table="Parent"
* proxy="test.Parent"
*/
public class Parent {
private Long parentId;
private Integer version;
private String field;
private Child child;

public Parent() {
}

/** Getter for property parentId.
* @hibernate.id
* generator-class="seqhilo"
* type="long"
* column="ParentId"
* unsaved-value="null"
* @hibernate.generator-param
* name="sequence"
* value="parent_sequence"
* @return Value of property parentId.
*
*/
public java.lang.Long getParentId() {
return parentId;
}

/** Setter for property parentId.
* @param parentId New value of property parentId.
*
*/
protected void setParentId(java.lang.Long parentId) {
this.parentId = parentId;
}

/** Getter for property version.
* @hibernate.version
* column=Version
* type=integer
* @return Value of property version.
*
*/
public java.lang.Integer getVersion() {
return version;
}

/** Setter for property version.
* @param version New value of property version.
*
*/
protected void setVersion(java.lang.Integer version) {
this.version = version;
}

/** Getter for property field.
* @hibernate.property
* column="Field"
* type="string"
* length="50"
* @return Value of property field.
*
*/
public java.lang.String getField() {
return field;
}

/** Setter for property field.
* @param field New value of property field.
*
*/
public void setField(java.lang.String field) {
this.field = field;
}

/** Getter for property child.
* @hibernate.one-to-one
* name="child"
* class="test.Child"
* cascade="save-update"
* outer-join="false"
* constrained="false"
* property-ref="parent"
* @return Value of property child.
*
*/
public test.Child getChild() {
return child;
}

/** Setter for property child.
* @param child New value of property child.
*
*/
public void setChild(test.Child child) {
this.child = child;
}

public String toString(){
return ToStringBuilder.reflectionToString(this).toString();
}
}


package test;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* @hibernate.class
* table="Child"
* proxy="test.Child"
*/
public class Child {

private Long childId;
private Integer version;
private String field;
private Parent parent;

public Child() {
}

/** Getter for property childId.
* @hibernate.id
* generator-class="seqhilo"
* type="long"
* column="ChildId"
* unsaved-value="null"
* @hibernate.generator-param
* name="sequence"
* value="child_sequence"
* @return Value of property childId.
*
*/
public java.lang.Long getChildId() {
return childId;
}

/** Setter for property childId.
* @param childId New value of property childId.
*
*/
public void setChildId(java.lang.Long childId) {
this.childId = childId;
}

/** Getter for property version.
* @return Value of property version.
*
*/
public java.lang.Integer getVersion() {
return version;
}

/** Setter for property version.
* @param version New value of property version.
*
*/
public void setVersion(java.lang.Integer version) {
this.version = version;
}

/** Getter for property field.
* @hibernate.property
* column="Field"
* type="string"
* length="50"
* @return Value of property field.
*
*/
public java.lang.String getField() {
return field;
}

/** Setter for property field.
* @param field New value of property field.
*
*/
public void setField(java.lang.String field) {
this.field = field;
}

/** Getter for property parent.
* @hibernate.many-to-one
* column="ParentId"
* class="test.Parent"
* cascade="none"
* not-null="true"
* outer-join="false"
* @return Value of property parent.
*
*/
public test.Parent getParent() {
return parent;
}

/** Setter for property parent.
* @param parent New value of property parent.
*
*/
public void setParent(test.Parent parent) {
this.parent = parent;
}

public String toString(){
return new ToStringBuilder(this)
.append("childId", childId)
.append("field", field)
.append("version", version)
.toString();
}
}

Mappings:

<?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>
<class
name="test.Parent"
table="Parent"
proxy="test.Parent"
dynamic-update="false"
>
<id
name="parentId"
column="ParentId"
type="long"
unsaved-value="null"
>
<generator class="seqhilo">
<param name="sequence">parent_sequence</param>
</generator>
</id>
<version
name="version"
type="java.lang.Integer"
column="version"
/>
<property
name="field"
type="string"
update="true"
insert="true"
column="Field"
length="50"
/>
<one-to-one
name="child"
class="test.Child"
cascade="save-update"
outer-join="false"
constrained="false"
property-ref="parent"
/>
</class>
</hibernate-mapping>

<?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>
<class
name="test.Child"
table="Child"
proxy="test.Child"
dynamic-update="false"
>
<id
name="childId"
column="ChildId"
type="long"
unsaved-value="null"
>
<generator class="seqhilo">
<param name="sequence">child_sequence</param>
</generator>
</id>
<property
name="field"
type="string"
update="true"
insert="true"
column="Field"
length="50"
/>
<many-to-one
name="parent"
class="test.Parent"
cascade="none"
outer-join="false"
update="true"
insert="true"
column="ParentId"
not-null="true"
/>

</class>
</hibernate-mapping>

Test methods:

private static void createParent() throws HibernateException {
Transaction tx = null;
Session session = null;

Parent parent = new Parent();
parent.setField("Parent_Field");

Child child = new Child();
child.setField("Child_Field");

parent.setChild(child);
child.setParent(parent);

try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
session.save(parent);
tx.commit();
}
catch (HibernateException he) {
if(tx!=null)
tx.rollback();
throw he;
}
finally {
if(session != null){
session.close();
}
}
}


public static Parent getParent(Long parentId) throws HibernateException{
Parent parent = null;
Transaction tx = null;
Session session = null;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
parent = (Parent)session.load(Parent.class, parentId);
tx.commit();
}
catch (HibernateException he) {
if(tx!=null)
tx.rollback();
throw he;
}
finally {
if(session != null){
session.close();
}
return parent;
}
}

I create a parent with the method createParent().
These are the issues I have:
1- If I remove proxy="test.Parent" from the parent's mapping, getParent always returns the parent with the child (sqls to get parent and child are executed, and parent.toString() executed after the session is closed shows the child):
Dec 6, 2003 4:04:17 PM net.sf.hibernate.cache.QueryCache <init>
INFO: starting query cache at region: net.sf.hibernate.cache.QueryCache
Hibernate: select parent0_.ParentId as ParentId0_, parent0_.version as version0_, parent0_.Field as Field0_ from Parent parent0_ where parent0_.ParentId=?
Hibernate: select child0_.ChildId as ChildId0_, child0_.Field as Field0_, child0_.ParentId as ParentId0_ from Child child0_ where child0_.ParentId=?

Found parent: test.Parent@15e0873[parentId=21,version=0,field=Parent_Field,child=test.Child@b7ec5d[childId=11,field=Child_Field,version=<null>]]


2- If I keep proxy="test.Parent" in the parent's mapping, the parent loaded by getParent() is not initialized (no sql is executed by Hibernate), and when I try use it I get the following exception:
INFO: starting update timestamps cache at region: net.sf.hibernate.cache.UpdateTimestampsCache
Dec 6, 2003 3:57:15 PM net.sf.hibernate.cache.QueryCache <init>
INFO: starting query cache at region: net.sf.hibernate.cache.QueryCache
Dec 6, 2003 3:57:15 PM net.sf.hibernate.proxy.LazyInitializer initializeWrapExceptions
SEVERE: Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed
at net.sf.hibernate.proxy.LazyInitializer.initialize(LazyInitializer.java:46)
at net.sf.hibernate.proxy.LazyInitializer.initializeWrapExceptions(LazyInitializer.java:56)
at net.sf.hibernate.proxy.LazyInitializer.getImplementation(LazyInitializer.java:156)
at net.sf.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:72)
at test.Parent$$EnhancerByCGLIB$$faa41c66.toString(<generated>)
at java.lang.String.valueOf(String.java:2177)
at java.lang.StringBuffer.append(StringBuffer.java:361)
at hibernate.Test.main(Test.java:26)

What am I missing to have lazy initialization for the child. I also need keep proxy="test.Parent" in the parent's mapping, as the parent is part of a graph, and I need this object also to be lazily initialized.

mota


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 7:41 pm 
Expert
Expert

Joined: Tue Sep 16, 2003 4:06 pm
Posts: 318
Location: St. Petersburg, Russia
As Emmanuel wrote, this is FAQ. Stupid me didn't read the FAQ :)
"constrainted" must be true in Parent->Child <one-to-one> mapping.

Code:
            outer-join="false"
            constrained="true"


works as expected - only Parent gets loaded (unless it uses proxy too)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 36 posts ]  Go to page 1, 2, 3  Next

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.