我很高兴这个社区存在,过去曾多次帮助我解决不同的小问题。 但现在我有一个更大的问题,花了将近两天的时间来寻找答案和解决方案,但不幸的是,我一无所获。 也许有人可以提供帮助并且之前遇到过类似的问题。
我会试着解释一下: 我想用项目构建一种树结构。 一个项目可以有多个子项目(例如文章(父项)及其成分(儿童))。这些子物品可以再生几个孩子等等。但是一个项目也可以有一个或多个过程(例如烹饪)。进程不需要像项目那样处于树结构中。 所以我构建了一个模型,它包含表Item,表ItemResource和表Process。每个表都有一个复合主键。表ItemResource应该是其他表的连接表,因此它将保留对父项的引用和对具体项的引用或对进程的引用。 因此它在PK中有一个属性resourceType,因此我们可以看到它是项目的资源还是要处理的资源。 我的方法(代码)看起来像这样:
@Entity
@Table(name="Item")
public class Item
{
@Getter @Setter
@EmbeddedId
private ItemIdPK id;
@Getter @Setter
@Column(name="name", length=50)
@Size(max=50)
private String name;
@Getter @Setter
@OneToMany(mappedBy = "parentItem")
private List<ItemResource> itemResources = new ArrayList<ItemResource>();
}
@Embeddable
public class ItemIdPK implements Serializable
{
public ItemIdPK() {
}
public ItemIdPK(String itemNumber, short mandator) {
this.itemNumber = itemNumber;
this.mandator = mandator;
}
@Getter @Setter
@Column(name="itemNumber", length=31)
@Size(max=31)
private String itemNumber;
@Getter @Setter
@Column(name="mandator")
@Size(max=2)
private short mandator;
}
@Entity
@Table(name="ItemResource")
public class ItemResource
{
@Getter @Setter
@EmbeddedId
private ItemResourceIdPK id;
@Getter @Setter
@Column(name="quantity")
private BigDecimal quantity; //extra column in join table
@Getter @Setter
@ManyToOne
@JoinColumns({
@JoinColumn(name = "refItemNumber", referencedColumnName="itemNumber", insertable = false, updatable = false),
@JoinColumn(name = "mandator", referencedColumnName="mandator", insertable = false, updatable = false)
})
private Item parentItem;
@Getter @Setter
@OneToOne
@JoinColumns({
@JoinColumn(name = "resourceNumber", referencedColumnName="itemNumber", insertable = false, updatable = false),
@JoinColumn(name = "mandator", referencedColumnName="mandator", insertable = false, updatable = false)
})
private Item item;
@Getter @Setter
@OneToOne
@JoinColumns({
@JoinColumn(name = "resourceNumber", referencedColumnName="processNumber", insertable = false, updatable = false),
@JoinColumn(name = "mandator", referencedColumnName="mandator", insertable = false, updatable = false)
})
private Process process;
}
@Embeddable
public class ItemResourceIdPK implements Serializable
{
public ItemResourceIdPK() {
}
public ItemResourceIdPK(String resourceNumber, short mandator, String refItemNumber, ResourceType resourceType) {
this.resourceNumber = resourceNumber;
this.mandator = mandator;
this.refItemNumber = refItemNumber;
this.resourceType = resourceType;
}
@Getter @Setter
@Column(name="refItemNumber", length=31) // --> reference for parent item
@Size(max=31)
private String refItemNumber;
@Getter @Setter
@Column(name="resourceNumber", length=31) // --> itemNumber or processNumber
@Size(max=31)
private String resourceNumber;
@Getter @Setter
@Column(name="mandator")
@Size(max=2)
private short mandator;
@Getter @Setter
@Column(name="resourceType", length=3)
@Enumerated(EnumType.STRING)
private ResourceType resourceType;
public enum ResourceType {
MA, //first type (for items)
AG; //second type (for processes)
public String value() {
return name();
}
public static ResourceType fromValue(String v) {
return valueOf(v);
}
}
}
@Entity
@Table(name="Process")
public class Process
{
@Getter @Setter
@EmbeddedId
private ProcessIdPK id;
@Getter @Setter
@Column(name="processName", length=50)
@Size(max=50)
private String processName;
public Process() {
}
public Process(String processName) {
super();
this.processName = processName;
}
}
@Embeddable
public class ProcessIdPK implements Serializable
{
public ProcessIdPK() {
}
public ProcessIdPK(String processNumber, short mandator) {
this.processNumber = processNumber;
this.mandator = mandator;
}
@Getter @Setter
@Column(name="processNumber", length=31)
@Size(max=31)
private String processNumber;
@Getter @Setter
@Column(name="mandator")
@Size(max=2)
private short mandator;
}
问题/结果: ddl自动生成在数据库中做得很好,除了ItemResource表中的两个外键约束,它们避免插入集合,如果在Item表或进程表中没有resourceNumber Id,即使我有不同的resourceType在PK中它们不同。 第二个问题是,在使用某些数据进行测试时,即使我只想加载项目(我认为是因为热切的加载),也有一个实体未找到表格的异常。 但是我怎样才能避免这些问题呢? JPA不可能吗?因为从数据库的逻辑方面来看,它必须是好的。 我能改变什么?数据库模型由客户提供,不应更改。
先致谢谢,并致以诚挚的问候, Bergerjung
P.S。:抱歉,也许这不是一个真正的JPA问题,除了不需要的外键约束,我可以在生成后删除,然后将自动更新设置为false。 也许它只是一个加载问题,并且有任何解决方案(资源类型条件为急切加载(因为OneToOne)进程或项目)。这有什么东西吗?