2014-10-23 1 views
0

У меня проблема с ленивой загрузкой в ​​спящем режиме при работе с/без наследования. Я использую hibernate как слой persistence. Мои сущности определяются с помощью аннотаций JPA. Я использую Jboss.Я получаю менеджер Entity с вводом источника данных. Я использую транзакции, управляемые контейнером. Eager не является правильным решением.Hibernate Доступ к свойствам класса не загружает реальный объект Hibernate

1) У меня есть один объект A, который ссылается на второй объект B.B-объект имеет некоторые атрибуты. Я знаю, что когда я обращаюсь к атрибутам B, он должен быть загружен Hibernate. Но это не так. Я получаю объект b_javaassist. Но я заметил, что когда объект отправляется клиенту, объект B успешно конвертируется в реальный объект. Это мой первый случай. Я не знаю, что мой второй случай такой же, как этот. Поэтому я расскажу в другом пункте.

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) У меня один объект а, который ссылается на второй объект B.B субъект имеет ссылки третье лицо, которое подклассы. Когда доступ элементов класса B, некоторые из них являются прокси-серверами BaseClass_javaasist, некоторые из них являются прокси-серверами SuperBaseClass_javaassist, некоторые из них являются реальным объектом SuperBaseClass. Я не понял, почему это происходит. Можете ли вы сказать мне, что мои дела различны или одинаковы? Каковы решения?

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 { 

} 

ответ

3

Hibernate использует прокси для осуществления ленивой загрузки. Это означает, что когда вы загружаете A, этот A ссылается на экземпляр класса, который является подклассом B, а также прокси для B. Таким образом, он IS a B по правилам наследования и полиморфизма.

При вызове метода в первый раз на этом прокси-сервере он инициализирует себя, получая данные B из базы данных, выполняет метод прокси-сервера B и возвращает тот же результат, что и в случае, если у вас не было прокси-сервера , Таким образом, нет проблем.

То же самое происходит с экземплярами BaseClass. Некоторые из них уже ссылаются на прокси-серверы, когда вы обращаетесь к элементам коллекции, и Hibernate таким образом ставит прокси в коллекции, чтобы убедиться, что один экземпляр когда-либо используется в одном сеансе для ссылки на один и тот же объект. Некоторые другие еще не сделали этого, и Hibernate затем помещает фактические экземпляры класса в коллекцию. Но это не имеет значения, потому что это все экземпляры BaseClass.

Так в основном, это так же, как делают

List<Number> list = new ArrayList<>(); 
list.add(new Integer(1)); 
list.add(new Long(2)); 

Список содержит Integer и Long экземпляры, но это все-таки список номер, и так как это все, что вы заботитесь о том, так как вы объявили список как Список, все нормально.

+0

Итак, что вы предлагаете, чтобы избавиться от этого? – user725455

+0

Избавиться от чего? В чем проблема. Все, что вы видите, нормальное, ожидаемое и правильное функционирование. –

+0

Я хочу получить реальные объекты, которые я могу прочитать некоторые атрибуты из них. Это невозможно. Даже Идентификатор этих объектов равен 0. – user725455