我不确定我缺少什么来建立双向的onetomany关系(hibernate引擎)。域模型的缩小版本:
class Person {
@OneToMany(mappedBy="personFrom", cascade = CascadeType.PERSIST)
public List<Relationship> relationships;
}
class Relationship {
@ManyToOne
public Person personFrom;
@ManyToOne
public Person personTo;
}
一些观察结果:
1.使用上面的映射,没有创建连接表
2.当我删除mappedBy(@OneToMany(cascade = CascadeType.PERSIST))时,创建了连接表,我可以通过Person持久保存。 “personFrom”字段为空,但我认为这是正常的,因为通过连接表维护关系。
我也试过通过在关系中指定连接列,没有任何区别。任何帮助,高度赞赏。 感谢。
根据Dan的评论,如果要查看域类的完整内容,我已在下面进行了扩展。
class Relationship extends Model{
@ManyToOne
public RelationshipType relationshipType;
@ManyToOne
public Person personFrom;
@ManyToOne
public Person personTo;
@ManyToOne
public Person createdBy;
@ManyToOne
public Role roleFrom;
@ManyToOne
public Role roleTo;
@Override
public String toString() {
return relationshipType.toString();
}
}
class Person extends Model {
public Date dateCreated;
@Lob
public String description;
@OneToMany(cascade = CascadeType.ALL)
public List<Role> roles;
@OneToMany(mappedBy="personFrom", cascade = CascadeType.PERSIST)
public List<Relationship> relationships;
}
角色也与Person有关,但我认为保持personFrom,personTo有助于优化我的查询。
Role extends Model {
@ManyToOne
public RoleType roleType;
@ManyToOne
public Person createdBy;
}
答案 0 :(得分:2)
使用上面的映射,没有创建连接表。
OneToMany
不需要连接表,您将在Many侧获得外键列。这就是我在使用您的代码时得到的结果:
create table Person (
id bigint not null,
primary key (id)
)
create table Relationship (
id bigint not null,
personFrom_id bigint,
personTo_id bigint,
primary key (id)
)
alter table Relationship
add constraint FK499B69164A731563
foreign key (personTo_id)
references Person
alter table Relationship
add constraint FK499B691698EA8314
foreign key (personFrom_id)
references Person
预期结果是什么(至少对我而言)。也许你真正想要的是ManyToMany
。
当我删除mappedBy(@OneToMany(cascade = CascadeType.PERSIST))时,会创建连接表,我可以通过Person持久保存。 “personFrom”字段为空,但我认为这是正常的,因为通过连接表维护关系。
我使用提供的代码编写了一个小单元测试(使用Hibernate的API,但这并没有改变任何东西)而且我没有得到问题所在(会话是在测试方法之前创建的,并且方法在交易):
Person p1 = new Person();
Person p2 = new Person();
Relationship r = new Relationship();
// create the personFrom bi-directional association
r.setPersonFrom(p1);
List<Relationship> relationships = new ArrayList<Relationship>();
relationships.add(r);
p1.setRelationships(relationships); // these four lines should be moved to some
// link management method (see update below).
// create the personTo uni-directional association
r.setPersonTo(p2);
session.persist(p2);
session.persist(p1);
assertNotNull(p2.getId());
assertNotNull(p1.getId());
assertNotNull(r.getId());
上面的代码导致Person表中的两个插入和Relationship表中的一个插入(估计3列)。
正如我所说,我没有遇到问题。也许您应该解释预期结果是什么(关系模型和查询)。
更新:要完全清楚,在处理双向关联时,您必须设置链接的两侧,并且常见的模式是使用防御性链接管理方法来正确设置双方该协会。像这样:
public void addToRelationships(Relationship relationship) {
if (this.relationships == null) {
this.relationships = new ArrayList<Relationship>();
}
this.relationships.add(relationship);
relationship.setPersonFrom(this);
}
详细信息请参阅Hibernate文档的1.2.6. Working bi-directional links部分。
答案 1 :(得分:0)
您是否指定了外键列名称作为连接列的名称?假设外键列名为PERSON_ID,代码应如下所示:
class Relationship {
@ManyToOne
@JoinColumn(name="PERSON_ID")
public Person personFrom;
...
}