2017-02-10 13 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 сохраняется вместе с объектом Person, который сохраняется вместе с сущностью Family. Также объект FamilyDetails сохраняется вместе с сущностью Family. Я пытался обновить атрибут homes из FamilyDetails перед тем, как продолжить создание объекта Family. Проблема в том, что добавленные дома еще не сохранились, когда я добавил их в коллекцию. Я полагал, что, когда они будут сохраняться вместе с лицами, лицами из семьи они будут обновлены также в коллекции домов из FamilyDetails но я получаюHibernate TransientObjectException при привязке к временным объектам

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: объект ссылается неспасенным переходный экземпляр - сохранить временный экземпляр перед промывкой: com.model.impl.Home;

Есть ли способ избежать этого?

+0

Попытки добавление каскада на главное лицо в FamilyDetails '@ManyToMany (выборка = FetchType.LAZY, targetEntity = Home.class, каскадный = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE)' – grizzly

ответ

0

Ну, очевидно: сохранить Home сек, прежде чем сохранить FamilyDetail с, что может быть достигнуто путем добавления @ManyToMany аннотации с атрибутом cascade, как гризли отметил в своем комментарии.

Подумайте об этом: Не настраивать какое-либо каскадное поведение походит на высказывание: Я позабочусь о сохранении этих. Почему JPA заботится о сохранении их и сохраняя их в правильном порядке, только потому, что это настроено где-то в другом месте относительно какого-либо другого объекта.