2016-08-11 10 views
0

У меня есть четыре модели:EclipseLink (JPA) два @OneToMany для одного и того же объекта?

Public class Product { 
     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Basic(optional = false) 
     @Column(name = "product_id") 
     private Long productId; 

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.LAZY, orphanRemoval = true) 
     private List<Director> directorList; 

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.LAZY, orphanRemoval = true) 
     private List<Actor> actorList; 
    } 
    public class Actor { 

     @MapsId("peopleId") 
     @JoinColumn(name = "people_id", referencedColumnName = "PEOPLE_ID", insertable = true, updatable = true) 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     private People people; 

     @MapsId("productId") 
     @JoinColumn(name = "product_id", referencedColumnName = "product_id", insertable = true, updatable = true) 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     private Product product; 
    } 
    public class Director { 
     @MapsId("peopleId") 
     @JoinColumn(name = "people_id", referencedColumnName = "PEOPLE_ID", insertable = true, updatable = true) 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     private People people; 

     @MapsId("productId") 
     @JoinColumn(name = "product_id", referencedColumnName = "product_id", insertable = true, updatable = true) 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     private Product product; 
    } 
    public class People { 
     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Basic(optional = false) 
     @Column(name = "PEOPLE_ID") 
     private Long peopleId; 
     private String name; 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "people", fetch = FetchType.LAZY) 
     private List<Director> directorList; 

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "people", fetch = FetchType.LAZY) 
     private List<Actor> actorList; 
    } 

Моя проблема здесь, когда я сохранить продукт с двумя списками, оба они содержат один и тот же человек имя и результат у меня есть две вставки в людях:

Product product = new Product(); 

    People people = new People(); 
    people.setName("John"); 

    Director director = new Director(); 
    director.setPeople(people); 
    product.getDirectorList().add(director); 

    Actor actor = new Actor(); 
    actor.setPeople(people); 
    product.getActorList().add(actor); 

    dao.update(p); 

Я тестировал изменение equals и hashcode лица, чтобы избежать дублирования, но не работает?

+0

вы должны упорствовать людей, а затем добавить управляемый объект списки –

+0

Я не могу вызывать какие-либо проблемы, кроме сохранения продукта, потому что объект содержит другое отношение. –

+0

Вы пробовали это? Конечно, вы можете сохранить объект без каких-либо отношений.Процесс будет: упорствовать в людях -> упорствовать режиссером и актером с постоянными людьми -> обновлять людей с постоянным режиссером и актером –

ответ

0

Во-первых, не понимаю фразу: нет не работать всегда буксировать строки

Во-вторых, зачем вам это нужно @MapsId?

В-третьих, зачем вам fetchType = FetchType.Lazy в @OneToMany, потому что это поведение по умолчанию?

Finnaly, я пробовал и работает. Конечно, нужно изменить порядок, потому что в некоторых отношениях у вас есть опция = false.

People people = new People(); 
    people.setName("John"); 
    entityManager.persist(people); --> Create people 

    Product product = new Product(); 
    entityManager.persist(product); --> Create product 

    Director director = new Director(); 
    director.setPeople(people); 
    director.setProduct(product); 
    entityManager.persist(director); --> Create director 

    Actor actor = new Actor(); 
    actor.setPeople(people); 
    actor.setProduct(product); 
    entityManager.persist(actor); --> Create actor 


    product.getDirectorList().add(director); 
    product.getActorList().add(actor); 
    entityManager.merge(product); --> update product 

    people.getActorList().add(actor); 
    people.getDirectorList().add(director); 

    entityManager.merge(people); --> update people 

Результат:

Люди

1 John 

Актер

ID PEOPLE_ID PRODUCT_ID 
4 1   2 

директор

ID PEOPLE_ID PRODUCT_ID 
3 1   2 

продукта

ID 
2 

Обновлено

ABaseEntity

@MappedSuperclass 
public class ABaseEntity { 

private int id; 

public ABaseEntity(int id) { 
    this.id = id; 
} 

public ABaseEntity() { 
} 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 
} 

директор

@Entity 
public class Director extends ABaseEntity{ 

private People people; 

private Product product; 

@JoinColumn(name = "people_id", referencedColumnName = "ID") 
@ManyToOne(optional = false, fetch = FetchType.LAZY) 
public People getPeople() { 
    return people; 
} 

public void setPeople(People people) { 
    this.people = people; 
} 

@JoinColumn(name = "product_id", referencedColumnName = "ID") 
@ManyToOne(optional = false, fetch = FetchType.LAZY) 
public Product getProduct() { 
    return product; 
} 

public void setProduct(Product product) { 
    this.product = product; 
} 
} 

Люди

@Entity 
public class People extends ABaseEntity { 

private String name; 
private List<Director> directorList = new ArrayList<>(); 


private List<Actor> actorList = new ArrayList<>(); 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

@OneToMany(cascade = CascadeType.ALL, mappedBy = "people") 
public List<Director> getDirectorList() { 
    return directorList; 
} 

public void setDirectorList(List<Director> directorList) { 
    this.directorList = directorList; 
} 

@OneToMany(cascade = CascadeType.ALL, mappedBy = "people") 
public List<Actor> getActorList() { 
    return actorList; 
} 

public void setActorList(List<Actor> actorList) { 
    this.actorList = actorList; 
} 
} 

Продукт

public class Product extends ABaseEntity{ 
private List<Director> directorList = new ArrayList<>(); 

private List<Actor> actorList = new ArrayList<>(); 

@OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true) 
public List<Director> getDirectorList() { 
    return directorList; 
} 

public void setDirectorList(List<Director> directorList) { 
    this.directorList = directorList; 
} 

@OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true) 
public List<Actor> getActorList() { 
    return actorList; 
} 

public void setActorList(List<Actor> actorList) { 
    this.actorList = actorList; 
} 
} 
+0

благодарю вас за ваше время, но проблема здесь у вас есть 6 транзакций в базе данных, что мне нужно в одной транзакции: entityManager.merge (продукт); делать все, что вы здесь делаете? можно объединить все объекты в каскаде? –

+0

На самом деле здесь 1 транзакция, 6 вызовов методов и jpa будет выполнять 4 запроса к базе данных. Количество транзакций не зависит от того, сколько раз вы вызываете метод на entityManager. Что касается вашего вопроса, я думаю, что вы не можете выполнить задачу одним вызовом метода для entityManager. Но мы можем вместе думать. –

+0

ok можно все это сделать в одном продукте.merge ?? –

0

решение я нашел, как Thanh нпо предложить так моя METHODE сохранить, как это:

Product product = new Product(); 

People people = new People(); 
people.setName("John"); 
dao.persist(people); 

Director director = new Director(); 
director.setPeople(people); 
product.getDirectorList().add(director); 

Actor actor = new Actor(); 
actor.setPeople(people); 
product.getActorList().add(actor); 

dao.update(p); 

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

  • Нет связанных вопросов^_^