Spring JPA ManyToOne - 在刷新之前保存瞬态实例

时间:2017-03-23 09:21:43

标签: java hibernate jpa spring-data-jpa

我创建了一个具有数据库访问权限的Spring Web Application。我有一个班级Person - 它引用了一个班级Address。一个人既有地址也有公司,因此personcompany都会引用Address表。我通过在人与地址以及公司之间定义@ManyToOne关系来做到这一点。

    @ManyToOne
    @JoinColumn (name="COMPANY_ID")
    private Adress companyId;

    @ManyToOne
    @JoinColumn (name="SUBSIDIARY_ID")
    private Adress subsidiaryId;

在人员存储库中,我有一个这样的保存方法:

 public Person save(Person entity) {

    SaveAccess<Person> ao = createSaveAccess();

    ao.setEntity(entity);
    ao.execute();
    return ao.getResult();
}

问题是,如果我尝试添加一个新人,我会Hibernate-TransientPropertyValueExceptionObject references an unsaved transient instance - save the transient instance before flushing.任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:0)

你能试试吗

@ManyToOne(cascade = CascadeType.ALL)

    @JoinColumn (name="COMPANY_ID")
    private Adress companyId;

   @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn (name="SUBSIDIARY_ID")
    private Adress subsidiaryId;

参考: Hibernate TransientPropertyValueException When saving data

https://dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-many-to-one-using-annotations-1.html

答案 1 :(得分:0)

我不认为地址包含如此多的数据,因此作为独立实体存储是合理的。出于性能考虑,我建议您使用embeddable + embedded类来实现此目的:

@Embeddable
public class Address
{
  String number;
  String street;
  String city;
  String country;
}

@Entity
public class Person
{
  @Id
  protected long id
  ...
  @Embedded
  Address address;
  @Embedded
  Address companyAddress;
  ...
}

如果你有一个遗留系统,你必须将地址存储在一个单独的表中,那么就有@SecondaryTable解决方案:

@Entity
@Table(name = "EMPLOYEE")
@SecondaryTable(name = "ADDRESS", pkJoinColumns = @PrimaryKeyJoinColumn(name = "EMPLOYEE_ID"))
public class Employee
{
    //...
    @Column(table = "ADDRESS")
    private Address address;

    @Column(table = "ADDRESS")
    private Address companyAddress;
}

答案 2 :(得分:0)

我遇到了类似的问题,即一个名为@OneToOne的表的Product注释与另一个名为Category的表的注释。我想指定每个Product必须有一个Category

因此,我必须确保将级联类型设置为CascadeTyoe.ALL,如下所示:

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "CATEGORY_NAME")
private Category category;