【问题标题】:Use entityManager to save into two tables with FK in one of the tables使用 entityManager 将 FK 保存到其中一张表中的两张表中
【发布时间】:2015-11-30 08:10:14
【问题描述】:

我必须使用 EntityManager 将第一个持久化实体的 ID 插入到表中。

我的实体有一个像这样生成的 ID

    @Id
@Column(name = "PUSH_ID", nullable = false)
@SequenceGenerator(name = "dbSequence", sequenceName = "VVV_PUSH_S", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dbSequence")
public Integer getIdentifier() {
    return identifier;
}

然后我持久化这个实体来生成 ID

        this.getEntityManager().persist(pushEntity);
        this.getEntityManager().flush();

我将 pushEntity.getIdentifier() 传递给一个 sql 语句,像这样插入到第二个表中

 selectQueryToInsert.addJoin(PUSH_SOURCE_TABLE, SQLJoinOperator.LEFT_JOIN, PUSH_SOURCE_TABLE + "." + SOURCE_ID_COLUMN + "=" + sourceTableName + "." + DEFAULT_ID_COLUMN + " AND " + PUSH_SOURCE_TABLE + "." + PUSH_ID_COLUMN + "=" +   String.valueOf(pushEntity.getIdentifier));
 selectQueryToInsert.addListValuesRestriction(sourceTableName, DEFAULT_ID_COLUMN, SQLOperator.IN, sourceList);
 selectQueryToInsert.addValueRestriction(PUSH_SOURCE_TABLE, PUSH_ID_COLUMN, SQLOperator.NULL, null);
 selectQueryToInsert.addSelectColumn(DEFAULT_ID_COLUMN);
 String insertQuery = INSERT_SOURCE_QUERY + stringBuilder.toString(selectQueryToInsert); 
 this.getEntityManager().createNativeQuery(insertQuery).executeUpdate();

技巧来了,在第二个表“PUSH_SOURCE_TABLE”中,我在 Push 的 ID 上有一个 FK,由于 entityManager 没有提交事务,所以 PUSH_ID 在数据库中尚不存在,第二次插入失败

integrity constraint (%s.%s) violated - parent key not found

有没有其他方法可以做到这一点。 tkx

【问题讨论】:

  • errm,为什么不先flush()呢?!
  • 我做了一个 this.getEntityManager().flush();在获得我传递给preparedStatement的ID之前
  • 日志说?它说明了所有已发出的 SQL,因此可以相对轻松地进行调试
  • 我已经解释过问题是 entityManager 即使使用 flush() 也不会提交,因此对于 DB,当执行语句时,表中尚不存在 push_id PK。这不是调试问题,如果存在的话,我需要一个不同的方法来做它的建议。 tkx
  • 实体管理器不会使用刷新提交...它会刷新...到数据存储。因此,原则上,您可以使用相同的连接并推送进一步的更新。当然,这取决于您为与 JPA 提供者的连接设置的事务隔离级别

标签: java hibernate jpa ejb-3.0


【解决方案1】:

我通过为我的 PUSH_SOURCE_TABLE 创建一个新实体而不是使用preparedStatement 解决了这个问题

并设置一个@Embeddable 类,像这样保存推送实体的父键

@Embeddable
public class PushEntityPK implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = -5599662020926504220L;

private Integer push_id;

private String entity_id;

//Default Constructor
public PushEntityPK(){

}

public PushEntityPK(Integer push_id, String entity_id){
    this.push_id = push_id;
    this.entity_id = entity_id;
}

并用@Idclass注释源表实体

@Entity
@Table(name = "PUSH_SOURCE_TABLE")
@IdClass(PushEntityPK.class)
public class PushSourceEntity implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 5162782386822573902L;

public PushSourceEntity(PushEntityPK pushEntityPK){
   this.push_id = pushEntityPK.getPush_id();
   this.entity_id = pushEntityPK.getSource_name();
}

@Id
@AttributeOverrides({@AttributeOverride(name = "push_id", column =   @Column(name = "PUSH_ID"))})
private Integer push_id;

@AttributeOverrides({@AttributeOverride(name = "entity_id", column = @Column(name = "ENTITY_ID"))})
private String entity_id;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多