Reputation: 475
I have a problem with lazy loading in hibernate when dealing with/Without inheritance. I am using hibernate as a persistence layer. My entities are defined using JPA annotations. I am using Jboss.I am getting Entity manager with data source injection. I am using container managed transactions. Eager is not proper solution.
1) I have one entity A that references a second entity B.B entity has some attributes. I know that when I access attributes of B, it should be loaded By Hibernate.But it does not .I get b_javaassist object.But I noticed that when A object is sent to client, B object is converted successfully to real object.This is my first case. I do not know my second case is same as this one. So I will tell in another item.
A aInstance = em.find(A.class, 1);
aInstance.getB().getName();
@Entity @Table(name="a")
public class A {
private B b;
}
@Entity @Table(name="b")
public class B {
private String name;
}
1) I have one entity A that references a second entity B.B entity has references a third entity that is subclassed. When access elements of B class, some of them are BaseClass_javaasist proxies , some of them are SuperBaseClass_javaassist proxies, some of them are real SuperBaseClass object. I did not get why it occurs. Can you please tell me my cases are different or same? What are the solutions?
A aInstance = em.find(A.class, 1);
aInstance.getB().getElements();
@Entity @Table(name="a")
public class A {
private B b;
}
@Entity @Table(name="b")
public class B {
private String name;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name="elements",
joinColumns={@JoinColumn(name="id", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="element_id", referencedColumnName="element_id")})
/** list of elements */
private List<BaseClass> elements = new ArrayList<BaseClass>();
}
@Entity @Table(name="superBaseClass")
public class SuperBaseClass extends BaseClass {
}
Upvotes: 0
Views: 1109
Reputation: 691765
Hibernate uses proxies to implement lazy-loading. This means that when you load an A, this A references an instance of a class that is a subclass of B, and also a proxy to B. So it IS a B, by the rules of inheritance and polymorphism.
When calling a method for the first time on this proxy, it initializes itself by getting the B data from the database, executes the method of the proxied B, and returns the same result as it would have if you had no proxy. There is thus no problem.
The same happens with your BaseClass instances. Some of them have already been referenced as proxies when you access the elements of the collection, and Hibernate thus puts the proxies in the collection, to make sure a single instance is ever used in the same session to reference the same entity. Some others haven't yet, and Hibernate then puts the actual class instances in the collection. But that doesn't matter, because they are all instances of BaseClass.
So basically, it's just the same as doing
List<Number> list = new ArrayList<>();
list.add(new Integer(1));
list.add(new Long(2));
The list contains Integer and Long instances, but it's still a list of Number, and since that's all you care about since you declared the list as a List, everything is normal.
Upvotes: 3