我认为我的休眠数据库设置不正确。我有Citizen
个实体,它们与WeeklyCare
实体具有一对多的关系。下面是相关代码。
公民:
@Entity
@Table(name = "citizens")
public class Citizen {
@Id
@Size(max = 10, min = 10, message = "CPR must be exactly 10 characters")
private String cpr;
@OneToMany()
@JoinColumn(name = "cpr")
private List<WeeklyCare> weeklyCare;
}
每周护理:
@Entity
public class WeeklyCare {
@EmbeddedId
private WeeklyCareIdentifier weeklyCareIdentifier;
}
WeeklyCareIdentifier:
@Embeddable
public class WeeklyCareIdentifier implements Serializable {
@NotNull
@Size(max = 10, min = 10, message = "CPR must tbe exactly 10 characters")
private String cpr;
@NotNull
private Integer week;
@NotNull
private Integer year;
}
要将数据保存到数据库时遇到一些问题:
WeeklyCare
,因为它需要Citizen
。 WeeklyCare
的列表。当我尝试拯救公民时,它给了我这个错误:Unable to find Application.Models.WeeklyCare with id Application.Models.WeeklyCareIdentifier@b23ef67b
我可以通过以下方法解决该问题:在保存之前清除WeeklyCare
上的Citizen
列表,然后在之后保存WeeklyCare
列表,但这听起来像是一种糟糕的方法做吧。
我想我想让休眠状态在保存WeeklyCare
时忽略Citizen
的列表,但是在获取Citizen
时确认它。这可能吗?还是有更好的方法呢?谢谢。
答案 0 :(得分:0)
- 我不能先保存WeeklyCare,因为它需要公民。
您在两个实体中使用了“ cpr”标识符:
Citizen
的主要ID WeeklyCare
的综合ID的一部分从理论上讲,您可以创建WeeklyCare
的列表(虽然现在不采用它的建模方式),然后将每个WeeklyCare
的关联更新为Citizen
。
- 当我将公民发送到后端时,这些对象包含WeeklyCare列表。当我试图拯救公民时,它给了我 错误:找不到ID为Application.Models.WeeklyCare Application.Models.WeeklyCareIdentifier@b23ef67b
映射一对多关联的最佳方法是双向。这还将使您免于仅在将@OneToMany与@JoinColumn一起使用时Hibernate生成的一些不必要的查询。
1)从WeeklyCareIdentifier
类中删除cpr(并可能重命名该类)。
@Embeddable
public class WeeklyCareIdentifier implements Serializable {
@NotNull
private Integer week;
@NotNull
private Integer year;
//constructors, getters, setters
}
2)删除复合@EmbeddedId,以使用Long id字段:
@Entity
public class WeeklyCare {
@Id
@GeneratedValue
private Long id;
@Embedded
private WeeklyCareIdentifier weeklyCareIdentifier;
//constructors, getters, setters
}
3)转到双向映射:
@Entity
@Table(name = "citizens")
public class Citizen {
@Id
@Size(max = 10, min = 10, message = "CPR must be exactly 10 characters")
private String cpr;
@OneToMany(
mappedBy = "citizen",
cascade = CascadeType.ALL, //cascade all operations to children
orphanRemoval = true //remove orphaned WeeklyCare if they don't have associated Citizen
)
private List<WeeklyCare> weeklyCares = new ArrayList<>(); //init collections to avoid nulls
//constructors, getters, setters
//add utility methods to manipulate the relationship
public void addWeeklyCare(WeeklyCare weeklyCare) {
weeklyCares.add(weeklyCare);
weeklyCare.setCitizen(this);
}
public void removeWeeklyCare(WeeklyCare weeklyCare) {
weeklyCares.remove(weeklyCare);
weeklyCare.setCitizen(null);
}
}
和:
@Entity
public class WeeklyCare {
@Id
@GeneratedValue
private Long id;
//having reference to the citizen entity from WeeklyCare
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "citizen_cpr")
private Citizen citizen;
@Embedded
private WeeklyCareIdentifier weeklyCareIdentifier;
//constructors, getters, setters
}
即使cpr是唯一的,我也建议对实体使用Long ID。将cpr转换为普通列,并在内部域中引入一个DB生成的ID列,您可以将其与之结合使用,并将cpr视为纯面向用户的数据列。