Можно ли соблюдать внешний ключ без картирования объекта-объекта?
-
22-09-2019 - |
Вопрос
Предполагая, что следующие сопоставления предоставляются:
<class name="A" table="a_table">
<id name="id"/>
<many-to-one name="entityB" column="fk_B" not-null="false" unique="true"/>
</class>
<class name="B" table="b_table">
<id name="id"/>
</class>
Java Class:
public class A {
private long id;
private B entityB;
// getters and setters skipped
}
Можно ли изменить картирование сгибания, чтобы, чтобы Иностранный ключ до сих пор применяется и создается Hibernate после стартапа, но класс A
будет выглядеть как следующее:
public class A {
private long id;
private long idOfB;
// getters and setters skipped
}
Я понимаю, что если я преобразую <many-to-one...
в а <property...
Это сработало бы, но иностранный ключ не будет применен базой данных.
Мне нужно сделать это, потому что объект B
может (или не может) инициализировать отдельно, что иногда вызываетorg.hibernate.LazyInitializationException: could not initialize proxy - no Session
Исключения возникают, когда a.getB()
называется. Я бы предпочел иметь это как 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>
Обратите внимание, когда два свойства имеют один и тот же столбец, Вы должны поместить настройки об этом только в одном свойстве. Анкет В противном случае, Hibernate будет жаловаться на некоторые ошибки. Это объясняет, почему я определяю Update = "false" и INSERT = "false" в свойстве EntityB.
С уважением,
Другие советы
Вы всегда можете создать DDL Foreign Key DDL вручную в своем файле HBM.XML HBM.XML:
<hibernate-mapping>
...
<database-object>
<create>[CREATE FK]</create>
<drop>[DROP FK]</drop>
</database-object>
</hibernate-mapping>
Вы также можете использовать это, если необходимо поддерживать разные диалекты.
Проверить 5.7 Объекты вспомогательной базы данных
Еще один подход, который вы могли бы использовать, - это определить 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;
}
}
Я рекомендую вам связывать объекты с объектами, чтобы получить полные преимущества Hibernate. Я думаю, что проблема в том, что вы получаете. Это потому, что сеанс Hibernate уже закрыт, когда вы пытаетесь получить ленивый объект. В этом блоге есть несколько сообщений, которые показывают ответы на эту проблему, например:ссылка текст.
В случае, если вы используете Spring, вы можете использовать OpenEntityManagerInViewFilter, чтобы сеанс будет открываться до тех пор, пока представление не будет рендерин.