Действительно ли возможно осуществить внешний ключ без отображения от объекта к объекту?

Принятие следующих отображений обеспечивается:


  
  



  

Класс 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
}

Я понимаю это, если я преобразовываю в a это работало бы, но внешний ключ не будет осуществлен базой данных.

Я должен сделать это потому что объект B мог бы (или не мог бы), будьте инициализированы отдельно, который иногда вызывает org.hibernate.LazyInitializationException: could not initialize proxy - no Session исключения для появления, когда a.getB() назван. Я предпочел бы иметь его как a long idOfB и загрузите целый объект каждый раз, когда необходимо; это также сделало бы загрузку объекта A более быстрый.

Я полагаю, что мой вопрос очень похож на этого, все же предлагаемое решение (для использования ленивой загрузки) не является соответствующим в моем случае как, даже если я звоню a.getB().getId(), Я добрался бы LazyInitializationException тогда как, если я звоню a.getIdOfB() Я не был бы.

Заранее большое спасибо.

6
задан Community 23 May 2017 в 12:33
поделиться

4 ответа

Как сказал

Я понимаю, что если я преобразую <много к одному ... в <свойство ... это будет работать, , но внешний ключ не будет применяться Отказ

Итак, мой совет: Используйте оба

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.

С уважением,

11
ответ дан 8 December 2019 в 16:02
поделиться

Другой подход, который вы можете предпринять, - это определить 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;
    }   
}
0
ответ дан 8 December 2019 в 16:02
поделиться

Вы всегда можете создать внешний ключ DDL вручную в вашем файле Hibernate HBM.xml:

<hibernate-mapping>
    ...
    <database-object>
        <create>[CREATE FK]</create>
        <drop>[DROP FK]</drop>
    </database-object> 
</hibernate-mapping>

Вы также можете включить это, если необходимо поддерживать разные диалекты.

Проверьте 5.7. Вспомогательные объекты базы данных

4
ответ дан 8 December 2019 в 16:02
поделиться

Я рекомендую вам ассоциировать объекты к объектам, чтобы получить полные преимущества гибернации. Я думаю, что проблема - это исключение, которое вы получаете. Это связано с тем, что сеанс Hibernate уже закрыт, когда вы пытаетесь получить ленивый объект. В этом блоге есть несколько сообщений, которые показывают ответы на эту проблему, например, этот: текст ссылки .

В случае, если вы используете пружину, вы можете использовать openEntitymanagerinviewfilter, поэтому сеанс будет открываться до того, как просмотр представления не будет.

0
ответ дан 8 December 2019 в 16:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: