2017-02-10 46 views
1
@Entity 
@Table(name = "PE_HOME") 
@Cacheable 
public class Home extends DefEntity implements IHome { 

    private static final long serialVersionUID = 1L; 

    @Column(name = "DESCRIPTION", nullable = true, unique = false) 
    private String description = null; 

    @Column(name = "INDICE", nullable = true, unique = false) 
    private Integer indice = null; 

    public Home() { 
     super(); 
    } 

    public String getDescription() { 
     return this.description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public Integer getIndice() { 
     return this.indice; 
    } 

    public void setIndice(Integer indice) { 
     this.indice = indice; 
    } 
} 


@Entity 
@Table(name = "PE_PERSON") 
public class Person extends DefEntity implements IPerson { 

    private static final long serialVersionUID = 1L; 

    @OneToOne(fetch = FetchType.LAZY, targetEntity = Home.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval = true) 
    @JoinColumn(name = "ID_HOME", nullable = true, unique = false) 
    private IHome home = null; 

    public Person() { 
     super(); 
    } 

    public IHome getHome() { 
     return this.home; 
    } 

    public void setHome(IHome home) { 
     this.home = home; 
    } 
} 

@Entity 
@Table(name = "PE_FAMILY") 
@Cacheable 
public class Family extends DefEntity implements IFamily { 

    private static final long serialVersionUID = 1L; 

    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
    @OneToMany(fetch = FetchType.LAZY, targetEntity = Person.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval = true) 
    @OrderColumn(name = "LIST_INDEX", nullable = false) 
    @JoinTable(name = "PE_FAMILY_PERSONS", joinColumns = { @JoinColumn(name = "ID_FAMILY") }, inverseJoinColumns = { @JoinColumn(name = "ID_PERSON") }, uniqueConstraints = @UniqueConstraint(columnNames = {"ID_PERSON", "LIST_INDEX" })) 
    private List<IPerson> persons = new ArrayList<IPerson>(); 

    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
    @OneToOne(fetch = FetchType.LAZY, targetEntity = FamilyDetails.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval = true) 
    @JoinColumn(name = "ID_FAM_DET", nullable = true, unique = true) 
    private IFamilyDetails familyDetails = null; 

    public Family() { 
     super(); 
    } 

    public List<IPerson> getPersons() { 
     return this.persons; 
    } 

    public void setPersons(List<IPerson> persons) { 
     this.persons = persons; 
    } 

    public IFamilyDetails getFamilyDetails() { 
     return this.familyDetails; 
    } 

    public void setFamilyDetails(IFamilyDetails familyDetails) { 
     this.familyDetails = familyDetails; 
    } 
} 


@Entity 
@Table(name = "PE_FAMILY_DETAILS") 
@Cacheable 
public class FamilyDetails extends DefEntity implements IFamilyDetails { 

    private static final long serialVersionUID = 1L; 

    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
    @ManyToMany(fetch = FetchType.LAZY, targetEntity = Home.class) 
    @JoinTable(name = "AX_FAM_DET_HOMES", joinColumns = { @JoinColumn(name = "ID_FAM_DET") }, inverseJoinColumns = { @JoinColumn(name = "ID_HOME") }) 
    private Set<IHome> homes = new HashSet<IHome>(); 

    public FamilyDetails() { 
     super(); 
    } 

    public Set<IHome> getHomes() { 
     return this.homes; 
    } 

    public void setHomes(Set<IHome> homes) { 
     this.homes = homes; 
    } 
} 

public class FamilyManager { 

    public void saveFamily(final IFamily family) { 
     updateFamilyDetails(family); 
     familyDao.save(family); 
    } 

    private void updateFamilyDetails(final IFamily family) { 
     IFamilyDetails details = family.getFamilyDetails(); 
     if (details == null) { 
      details = new FamilyDetails(); 
      family.setFamilyDetails(details); 
     } 
     details.getHomes().clear(); 
     for (IPerson p : family.getPersons()) { 
      if (p.getHome() != null) { 
       details.getHomes().add(p.getHome()); 
      } 
     } 
    } 
} 

因此,Home實體與持有與Family實體一起保持的Person實體一直持久。此外,FamilyDetails實體與Family實體一起被保存。在持久化Family實體之前,我試圖從FamilyDetails更新家庭屬性。問題在於,當我將它們添加到收藏中時,添加的房屋還沒有持續存在。我相信,當他們與來自Family的Persons實體一起堅持時,他們也會在FamilyDetails的家庭收藏中更新,但我得到的org.springframework.dao.InvalidDataAccessApiUsageException:org.hibernate.TransientObjectException:對象引用未保存瞬態實例 - 在刷新之前保存瞬態實例:com.model.impl.Home;當引用瞬態實體時Hibernate TransientObjectException

有沒有辦法避免這種情況?

+0

嘗試在FamilyDetails中添加級聯到家庭實體 '@ManyToMany(fetch = FetchType.LAZY,targetEntity = Home.class,cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE) – grizzly

回答

0

很明顯嘛:保存Home是你救FamilyDetail s,這可以通過添加註釋@ManyToManycascade屬性作爲灰熊在他的評論中指出的實現了。

想一想:不配置任何級聯行爲就像說:我照顧堅持這些。爲什麼JPA應該小心地堅持並堅持正確的順序,只是因爲這是在別的地方相對於其他實體配置的。