2016-10-03 2 views
1

у меня есть к таблицам с круговой ссылкойКак Hibernate Аннотации с циклическими ссылками

-----------------|     |------------------ 
    product  |     | product_detail 
-----------------|     |------------------ 
product_id <pk> |     | detail_id <pk> 
    ...   | <-----------------| container_id <fk> 
       | <-----------------| product_id <fk> 
       |     | ... 

Я хочу знать, как сделать аннотации собственности

Как сделать @OneToMany аннотацию

Class Product 
@OneToMany ??? 
public List<Detail> getDetails(); 

Как сделать @ManyToOne аннотаций

Class Detail 

@ManyToOne ??? 
public Product getContainer(); 

@ManyToOne ??? 
public Product getProduct(); 

Я хочу использовать следующий код позже:

Product p1 = new Product(name2); 
    Product p2 = new Product(name1); 

    Detail d = new Detail(); 

    d.setProduct(p2); 

    p1.getDetails().add(d); 

    ... 

    Session.save(p1); 

Затем Hibernate вставки в продукт и вставить в детали слишком.

Я не нахожу способ создания аннотаций для этого. Не могли бы вы мне помочь?

+0

https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_OneToMany_relationship_and_inverse_ManyToOne_annotations –

+0

mappedBy (на '@ OneToMany') делает его BIDIRECTIONAL отношение. Вот и все, что необходимо –

+0

Да, это было так, как я пробовал до публикации, но затем я получил превышение времени ожидания. @OneToMany (mappedBy = "container") для списка getDetails() и @ManyToOne @JoinColumn (name = "container_id") для getContainer() – axiorema

ответ

1

В вашей ситуации ваш код должен выглядеть следующим образом:

Class Product 
@OneToMany(mappedBy = "product") 
public List<Detail> getDetails(); 

Для класса Detail вы должны быть в состоянии использовать @ManyToOne аннотации, как есть. Итак:

Class Detail 
@ManyToOne 
public Product getContainer(); 

@ManyToOne 
public Product getProduct(); 

Смысл этого в том, что в вашем @OneToMany вы отметить в параметре mappedBy, какое поле в классе Detail имеет в виду этот продукт. Вам не нужна дополнительная информация в аннотации @ManyToOne, если вы придерживаетесь стандартных соглашений об именах.

+0

с этим решением подробно objet не вставлен в db, только продукты – axiorema

+0

Hi axiorema, please посмотрите https://vladmihalcea.com/2015/03/05/a-beginners-guide-to-jpa-and-hibernate-cascade-types/, а затем просмотрите раздел «один ко многим». Добавление cascade = CascadeType.PERSIST к вашей аннотации @OneToMany должно заботиться о сохранении детей вместе с вашим родителем. –

0

Я пробовал решения, размещенные с помощью mappedBy, но затем, когда я запускаю пример кода, только продукты вставляются на db.

Единственный способом я нашел, что это работает отлично используют аннотации с OneToMany владельца стороны:

Class Detail 
    @ManyToOne(cascade={CascadeType.ALL}) 
    @JoinColumn(name="container_id") 
    public Product getContainer() { 

    @ManyToOne 
    @JoinColumn(name="product_id") 
    public Product getProduct() { 

Class Product 
    @OneToMany(cascade={CascadeType.ALL}) 
    @JoinColumn(name="container_id") 
    public Set<Detail> getDetails() 

это пример код:

Product p1 = new Product("the container"); 
    Product p2 = new Product("the product"); 

    Detail d = new Detail(); 

    d.setProduct(p2); 

    p1.getDetails().add(d); 

    session.save(p2); 
    session.save(p1); 

в данном случае от двух продуктов вставлены и деталь также вставлена.

Но есть неудобный, потому что если я не хочу получать:

SQLIntegrityConstraintViolationException: Column 'container_id' cannot be null 

я должен изменить де таблицы детализации и настроить внешний ключ «container_id» в NULL, и это не совпадают с моделью

CHANGE COLUMN `container_id` `container_id` INT(11) NULL 

где деталь должна всегда иметь контейнерный продукт.

Может ли кто-нибудь пролить свет на предмет?

Смежные вопросы