如何为连接表指定其他插入信息?

时间:2014-02-12 18:03:26

标签: java jpa eclipselink spring-data-jpa

我有一个实体,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关系。如何省略第二次插入?

1 个答案:

答案 0 :(得分:1)

除非该字段是某种索引,或者您想使用映射并将该字段用作键或值,JPA仅允许在实体中映射字段。

因此,为了便于移植而不必进入提供者细节,您需要为该关系表创建一个实体。这允许该字段在查询中使用,并像任何其他字段一样进行访问。