Hi there.
I think I've found a problem with Hibernate Annotations regarding proxied entities. If the proxied entity has its @Id-annotation on the id-field (instead of the getId-method), the proxied entity are fetched when getId() is called.
Hibernate version:
3.2.5.ga, Annotations: 3.3.0.ga
Test case
Parent.java:
Code:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Parent{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
Child.java:
Code:
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public Parent getParent() {
return parent;
}
public void setParent(final Parent parent) {
this.parent = parent;
}
}
LazyLoadingWithFieldLevelAnnotationsTest:
Code:
import junit.framework.TestCase;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hsqldb.jdbcDriver;
public class LazyLoadingWithFieldLevelAnnotationsTest extends TestCase {
SessionFactory sessionFactory;
public Session getSession() throws HibernateException {
return sessionFactory.openSession();
}
@Override
protected void setUp() throws Exception {
// load the hsqldb jdbc driver
Class.forName(jdbcDriver.class.getName());
// setup session-factory
sessionFactory = new AnnotationConfiguration().addAnnotatedClass(Child.class).addAnnotatedClass(Parent.class).setProperty("hibernate.dialect",
"org.hibernate.dialect.HSQLDialect").setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:temptest").setProperty("hibernate.hbm2ddl.auto", "create-drop")
.buildSessionFactory();
}
public void testLazyLoadingWithFieldLevelAnnotations() throws Exception {
Session session = getSession();
session.beginTransaction();
// save a parent and a child, connected to that parent
final Parent p = new Parent();
session.save(p);
Child c = new Child();
c.setParent(p);
session.save(c);
assertNotNull(c.getId());
// close the session and open a new one
session.getTransaction().commit();
session.close();
session = getSession();
// get the child from the database
c = (Child) session.get(Child.class, c.getId());
assertNotNull(c);
assertNotNull(c.getParent());
// assert that the parent is currently not initialized
assertFalse(Hibernate.isInitialized(c.getParent()));
assertNotNull(c.getParent().getId());
// assert that the parent still is not initialized
assertFalse(Hibernate.isInitialized(c.getParent()));
}
}
Test result:
Code:
junit.framework.AssertionFailedError
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertFalse(Assert.java:34)
at junit.framework.Assert.assertFalse(Assert.java:41)
at LazyLoadingWithFieldLevelAnnotationsTest.testLazyLoadingWithFieldLevelAnnotations(LazyLoadingWithFieldLevelAnnotationsTest.java:58)
(...)
If the @Id-annotation on Parent.java are moved down from the field to the getId-method, the test runs without any problems.
Aleksander Blomskøld