Можно ли соблюдать внешний ключ без картирования объекта-объекта?

StackOverflow https://stackoverflow.com/questions/2111294

Вопрос

Предполагая, что следующие сопоставления предоставляются:

<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, чтобы сеанс будет открываться до тех пор, пока представление не будет рендерин.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top