我是JPA的新手。我有一个我认为是一个非常简单的例子,但我在实现它时遇到了麻烦。基本上,我有一个我想在其他实体中“重用”的实体。
我有一个User
有两个字段 - Home
和Office
。其中每一个都依次引用Address
,如下所示:
@Entity
public class User extends Model {
@Column
private String name;
@OneToOne
private Home home;
@OneToOne
private Office office;
}
@Entity
public class Home extends Model {
@OneToOne
private Address address;
@OneToOne(mappedBy="home")
private User user;
// ...
}
@Entity
public class Office extends Model {
@OneToOne
private Address address;
@OneToOne(mappedBy = "office")
private User user;
// ...
}
@Entity
public class Address extends Model {
@Column
private String line1;
@Column
private String line2;
@Column
private String city;
/*
* Is this possible? Being owned by two entities?
*/
@OneToOne(mappedBy="address")
private Home home;
@OneToOne(mappedBy="address")
private Office office;
// ...
}
我如何实现这一目标?
我最初遇到这个例外:
org.hibernate.AnnotationException: @OneToOne or @ManyToOne on example.Home.address references an unknown entity: example.Address
事实证明,其中一个类已从@Entity
而非org.hibernate
导入javax.persistence
注释。解决这个问题后,最初的例外消失了(this帮助我确定了问题)
但是,我现在有一个新例外:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: example.User.home -> example.Home
我对此并不十分了解。我应该在save
实例之前调用Home
User
对象吗?
答案 0 :(得分:1)
我通过向所有实体中的所有cascade=CascadeType.ALL
注释添加@OnetoOne
属性来解决问题。
如果没有此注释,在保存拥有之前,我必须save
每个拥有的实体。例如,在保存住所属的Home
之前,我必须先保存User
。
将cascade
属性添加到注释会为您解决此问题。您只需保存User
即可自动为您保存Home
和Address
。
This帖子帮我解决了这个问题。
答案 1 :(得分:1)
你能只做一个用户:
@Entity public class User extends Model
{
@Column
private String name;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "line1", column = @Column(name="column11")),
@AttributeOverride(name = "line2", column = @Column(name="column21")),
@AttributeOverride(name = "city", column = @Column(name="column31"))
})
private Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "line1", column = @Column(name="column12")),
@AttributeOverride(name = "line2", column = @Column(name="column22")),
@AttributeOverride(name = "city", column = @Column(name="column32"))
})
private Address officeAddress;
// .. setters, getters
}
@Embeddable
public class Address extends Model
{
private String line1;
private String line2;
private String city;
// .. getters, setters
}