Java 使用entityManager将FK保存到其中一个表中的两个表中

Java 使用entityManager将FK保存到其中一个表中的两个表中,java,hibernate,jpa,ejb-3.0,Java,Hibernate,Jpa,Ejb 3.0,我必须使用EntityManager将第一个持久化enity的ID插入表中 我的实体有一个这样生成的ID @Id @Column(name = "PUSH_ID", nullable = false) @SequenceGenerator(name = "dbSequence", sequenceName = "VVV_PUSH_S", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, gene

我必须使用EntityManager将第一个持久化enity的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;
}
 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();
然后我持久化这个实体以生成ID

        this.getEntityManager().persist(pushEntity);
        this.getEntityManager().flush();
我将pushEntity.getIdentifier()传递给sql语句,以便像这样插入到第二个表中

    @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;
}
 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

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

设置一个@Embeddeble类,该类持有push实体的父键,如下所示

@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;

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