我有一个实体,Item,通过连接表与其他Items相关。但是,我需要插入" additionalField"的值。当持久化相关项目时。
我使用spring数据JPA(1.4.1)进行持久性抽象。 EclipseLink(2.5.0)是我的JPA提供者。
@Entity
public class Item {
// other fields and getters/setters omitted for clarity
@OneToMany
@JoinTable(name = "related_items_map",
joinColumns = @JoinColumn(name = "fk_item"),
inverseJoinColumns = @JoinColumn(name = "fk_related_item"))
private List<Item> relatedItems;
}
join table name = "related_items_map" with
columns = fk_item, fk_related_item, additionalField
我的最终目标是实现以下语义:
// obtain the items from service by id
Item item = itemService.findOne(1);
Item relatedItem = itemService.findOne(2);
// add related item to item related list
item.getRelatedItems().add(relatedItem);
// save item using service
itemService.save(item);
今天生成的SQL看起来正确
INSERT INTO item (fk_item, fk_related_item) values (?, ?) => bind [1, 2]
唯一的问题是additionalField列为null。应插入的值应在插入之前的运行时计算(基于某些状态)。
如何自定义此操作的插入?我知道如何自定义特定的类,而不是映射。
====更新====
正如克里斯所建议的,我创建了一个包含&#34; JoinTable&#34;
的实体@Entity
@Table("related_items_map")
public class RelatedItem {
@Id
private String itemId;
@Id
private String relatedItemId;
// ... other stuff
}
@Entity
public class Item {
// other fields and getters/setters omitted for clarity
@OneToMany
@JoinTable(name = "related_items_map",
joinColumns = @JoinColumn(name = "fk_item"))
private List<RelatedItem> relatedItems;
}
但是,当我执行以下操作时,eclipselink正尝试执行多次插入:
// obtain two items
Item item = itemService.find(1);
Item other = itemService.find(2);
// create the joining
RelatedItem relatedItem = new RelatedItem();
relatedItem.setItemId(item.getId());
relatedItem.setRelatedId(other.getId());
// add the relation to the list of relations
item.getRelatedItems().add(relatedItem);
// update the item.
itemService.save(item);
我收到了一个关键约束违规,因为它试图进行两次插入:
INSERT INTO related_items_map(fk_item, fk_related_item, ...) values (?, ?, ...) => bind [1, 2, ...]
INSERT INTO related_items_map(fk_item, fk_related_item) values (?, ?) => bind [1 ,2]
我假设的第一个插入,因为它正在创建实际的实体。我假设的第二个是因为Item类上的OneToMany关系。如何省略第二次插入?
答案 0 :(得分:1)
除非该字段是某种索引,或者您想使用映射并将该字段用作键或值,JPA仅允许在实体中映射字段。
因此,为了便于移植而不必进入提供者细节,您需要为该关系表创建一个实体。这允许该字段在查询中使用,并像任何其他字段一样进行访问。