Принятие следующих отображений обеспечивается:
Класс Java:
public class A {
private long id;
private B entityB;
// getters and setters skipped
}
Действительно ли возможно изменить Быть в спящем режиме отображение так, чтобы внешний ключ был все еще осуществлен и создан, в спящем режиме после запуска, но класса A
был бы похож как следующее:
public class A {
private long id;
private long idOfB;
// getters and setters skipped
}
Я понимаю это, если я преобразовываю
Я должен сделать это потому что объект B
мог бы (или не мог бы), будьте инициализированы отдельно, который иногда вызывает org.hibernate.LazyInitializationException: could not initialize proxy - no Session
исключения для появления, когда a.getB()
назван. Я предпочел бы иметь его как a long idOfB
и загрузите целый объект каждый раз, когда необходимо; это также сделало бы загрузку объекта A
более быстрый.
Я полагаю, что мой вопрос очень похож на этого, все же предлагаемое решение (для использования ленивой загрузки) не является соответствующим в моем случае как, даже если я звоню a.getB().getId()
, Я добрался бы LazyInitializationException
тогда как, если я звоню a.getIdOfB()
Я не был бы.
Заранее большое спасибо.
Как сказал
Я понимаю, что если я преобразую <много к одному ... в <свойство ... это будет работать, , но внешний ключ не будет применяться Отказ
Итак, мой совет: Используйте оба
public class EntityA {
private Integer idOfB;
private EntityB entityB;
// getter's and setter's
}
, так и
<class name="A" table="a_table">
<id name="id"/>
<property name="idOfB" column="fk_B" not-null="false" unique="true"/>
<many-to-one name="entityB" update="false" insert="false" column="fk_B"/>
</class>
, когда два свойства имеют одну и ту же столбец, Вы должны поместить настройки об этом только в одном свойстве . В противном случае гибернат будет жаловаться на некоторые ошибки. Это объясняет, почему я определяю обновление = «ложь» и вставьте = «ложь» в свойстве EntityB.
С уважением,
Другой подход, который вы можете предпринять, - это определить FK со своим сопоставлением B, а не сопоставлением. Я добавил код JPA, вам нужно будет перевести это на ваш файл отображения Hibernate, если вы не используете аннотации.
@Entity
public class B
{
private long id;
private List<A> aList;
@Id
@Column( name = "ID" )
public long getId()
{
return id;
}
@OneToMany
@JoinColumn( name = "B_ID" )
public List<A> getAList()
{
return aList;
}
public void setId( long id )
{
this.id = id;
}
public void setAList( List<A> aList )
{
this.aList = aList;
}
}
А.Ява не выглядел так:
@Entity
public class A
{
private long id;
private long idOfB;
@Id
@Column( name = "ID" )
public long getId()
{
return id;
}
@Column( name = "B_ID" )
public long getIdOfB()
{
return idOfB;
}
public void setId( long id )
{
this.id = id;
}
public void setIdOfB( long idOfB )
{
this.idOfB = idOfB;
}
}
Вы всегда можете создать внешний ключ DDL вручную в вашем файле Hibernate HBM.xml:
<hibernate-mapping>
...
<database-object>
<create>[CREATE FK]</create>
<drop>[DROP FK]</drop>
</database-object>
</hibernate-mapping>
Вы также можете включить это, если необходимо поддерживать разные диалекты.
Проверьте 5.7. Вспомогательные объекты базы данных
Я рекомендую вам ассоциировать объекты к объектам, чтобы получить полные преимущества гибернации. Я думаю, что проблема - это исключение, которое вы получаете. Это связано с тем, что сеанс Hibernate уже закрыт, когда вы пытаетесь получить ленивый объект. В этом блоге есть несколько сообщений, которые показывают ответы на эту проблему, например, этот: текст ссылки .
В случае, если вы используете пружину, вы можете использовать openEntitymanagerinviewfilter, поэтому сеанс будет открываться до того, как просмотр представления не будет.