【问题标题】:Persisting 2 table with the same generated id持久化 2 个具有相同生成 id 的表
【发布时间】:2016-06-02 10:06:23
【问题描述】:

我尝试持久化一个与另一个子实体连接的父实体,但问题是在持久化时没有为这个子实体生成 id,所以我有这个错误:[org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ORA-01400: cannot insert NULL into ("L2S$OWNER"."SABRI"."TRANSITION_MATRIX_ID")

有子实体:

@Data
@Entity
@IdClass(MyLibrarySabriEntityPK.class)
@Table(name = "SABRI", schema = "L2S$OWNER", catalog = "")

public class MyLibrarySabriEntity extends ActionForm {
@Access(AccessType.FIELD)
@Id
@ManyToOne
@JoinColumn(name = "TRANSITION_MATRIX_ID", referencedColumnName = "ID_TRANSITION_MATRIX")
private MyLibraryTestEntity sabriEntity;

@Id
private String RATING_ID_ROW;

@Id
private String RATING_ID_COL;


@Basic
@Column(name = "TRANSITION_PROBABILITY", nullable = true, insertable = true, updatable = true, precision = 20)
private Double TRANSITION_PROBABILITY;}

PK类:

@Data
public class MyLibrarySabriEntityPK implements Serializable {
private String TRANSITION_MATRIX_ID;
private String RATING_ID_ROW;
private String RATING_ID_COL;


public MyLibrarySabriEntityPK(String TRANSITION_MATRIX_ID,String RATING_ID_COL,String RATING_ID_ROW ){
    this.TRANSITION_MATRIX_ID=TRANSITION_MATRIX_ID;
    this.RATING_ID_COL = RATING_ID_COL;
    this.RATING_ID_ROW= RATING_ID_ROW;
}

}

有父实体:

@Data
@Entity
@Table(name = "TEST", schema = "L2S$OWNER", catalog = "")
public class MyLibraryTestEntity extends ActionForm {

    @Access(AccessType.FIELD)
    @OneToMany(mappedBy = "sabriEntity", cascade = CascadeType.PERSIST)
    private final List<MyLibrarySabriEntity> entities = new ArrayList<MyLibrarySabriEntity>(25);

    public void addEntitysabri(MyLibrarySabriEntity entity) {
        getEntities().add(entity);
        entity.setSabriEntity(this);
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "IdGenerated")
    @GenericGenerator(name = "IdGenerated", strategy = "dao.Identifier")
    @Column(name = "ID_TRANSITION_MATRIX", nullable = false, insertable = false, updatable = false, length = 10)
    private String ID_TRANSITION_MATRIX;


    @Basic
    @Column(name = "REFERENCE", nullable = true, insertable = true, updatable = true, precision = 0)
    private Integer reference;}

在这里,我尝试保留应该保留子表的父表,但没有生成 Id!

MyLibrarySabriEntity Entity = null;
MyLibraryTestEntity test = getMyLibraryTestEntity(matrixStartDate, matrixName);  // here I get the values of my entity test (parent)
    try {
        transaction.begin();
        for (int row = 0; row < 20; row++) {
            for (int col = 0; col < 20; col++) {
                double val = cells.get(row + FIRST_ROW, col + FIRST_COL).getDoubleValue();
                Entity = getMyLibrarySabriEntity(col, row, val); // this get the values of the Entity parameters (child)
                Entity.setSabriEntity(test);
                test.addEntitysabri(Entity);
                em.persist(test);
            }
        }


    } catch (Exception e) {
        if (transaction.isActive())
            transaction.rollback();
        LOGGER.warn(e.getMessage(), e);

    } finally {
        if (transaction.isActive())
            transaction.commit();
        em.close();

    }

【问题讨论】:

  • 貌似,没有正确配置依赖bean,请重新检查。
  • 为什么标题上写着“生成的 id 相同”?子实体“MyLibraryTestEntity”将拥有自己的 id,父实体将拥有自己的 ID,前提是您正确配置了 beans 的依赖关系。
  • MyLibraryTestEntity 它是父实体,子实体是 MyLibrarySabriEntity ,你说得对,它不是同一个 id 因为子 id 有 3 个 id 所以,我的意思是父实体生成的 id 的值将是与我的子实体的 TRANSITION_MATRIX_ID 列的值相同

标签: java hibernate jpa transactions hibernate-entitymanager


【解决方案1】:

假设您使用的是 JPA 2.0+

完全删除此映射:

@Id
@Column(name = "TRANSITION_MATRIX_ID", nullable = false, 
       insertable = true, updatable = true, length = 100)
private String TRANSITION_MATRIX_ID;

并将@Id 直接放在ManyToOne 上并删除可插入和可更新的属性。

@Access(AccessType.FIELD)
@Id
@ManyToOne
@JoinColumn(name = "TRANSITION_MATRIX_ID", referencedColumnName = "ID_TRANSITION_MATRIX")
private MyLibraryTestEntity sabriEntity;

相应地更新您的 ID 类。以前对TRANSITION_MATRIX_ID 的任何引用都应替换为对sabriEntity 的引用。您还混淆了@EmbeddedId 和@IdClass:只有前者会包含列定义,而您使用的是后一种方法。

public class MyLibrarySabriEntityPK implements Serializable {

    private String sabriEntity;
    private String RATING_ID_ROW;
    private String RATING_ID_COL;
}

见:

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#JPA_2.0

【讨论】:

  • 我这样做了,但我有这个错误:“无法在使用@IdClass:model.MyLibrarySabriEntity 注释的实体中找到属性(TRANSITION_MATRIX_ID)”,问题是我无法删除它,因为我有3 列作为 Id 不只是 2 !
  • ID 类中的属性应与实体中的属性相匹配,以便为sabriEntity 而不是TRANSITION_MATRIX_ID
  • 我试图删除它,但我遇到了同样的错误“无法将 NULL 插入 ("L2S$OWNER"."SABRI"."TRANSITION_MATRIX_ID")”。
  • 我还建议在 JoinColumn 上将 insertable 和 updateable 设置为 false 不太可能做得很好。
  • 当我将他设置为 true 时,它​​给了我这个错误“实体映射中的重复列:model.MyLibrarySabriEntity 列:TRANSITION_MATRIX_ID”这是正常的,因为我已经有了同名的列跨度>
【解决方案2】:

感谢 Alan Hay,我发现了问题,我将我的 IDclass 的属性 TRANSITION_MATRIX_ID 更改为 sabriEntity 并删除了该类的所有注释!

子实体

@Data
@Entity
@IdClass(MyLibrarySabriEntityPK.class)
@Table(name = "SABRI", schema = "L2S$OWNER", catalog = "")
public class MyLibrarySabriEntity extends ActionForm {

@Access(AccessType.FIELD)
@ManyToOne
@Id
@JoinColumn(name = "TRANSITION_MATRIX_ID", referencedColumnName = "ID_TRANSITION_MATRIX")
private MyLibraryTestEntity sabriEntity;


@Id
private String RATING_ID_ROW;

@Id
private String RATING_ID_COL;


@Basic
@Column(name = "TRANSITION_PROBABILITY", nullable = true, insertable = true, updatable = true, precision = 20)
private Double TRANSITION_PROBABILITY;

父实体

@Data
@Entity
@Table(name = "TEST", schema = "L2S$OWNER", catalog = "")
public class MyLibraryTestEntity extends ActionForm {

@Access(AccessType.FIELD)
@OneToMany(mappedBy = "sabriEntity", cascade = CascadeType.PERSIST)
private final List<MyLibrarySabriEntity> entities = new ArrayList<MyLibrarySabriEntity>(25);

public void addEntitysabri(MyLibrarySabriEntity entity) {
    getEntities().add(entity);
    entity.setSabriEntity(this);
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "IdGenerated")
@GenericGenerator(name = "IdGenerated", strategy = "dao.Identifier")
@Column(name = "ID_TRANSITION_MATRIX", nullable = false, insertable = false, updatable = false, length = 10)
private String ID_TRANSITION_MATRIX;


@Basic
@Column(name = "REFERENCE", nullable = true, insertable = true, updatable = true, precision = 0)
private Integer reference;

PK类

@Data
public class MyLibrarySabriEntityPK implements Serializable {
private MyLibraryTestEntity sabriEntity;
private String RATING_ID_ROW;
private String RATING_ID_COL;

public MyLibrarySabriEntityPK() {
}

public MyLibrarySabriEntityPK(MyLibraryTestEntity sabriEntity,String RATING_ID_COL,String RATING_ID_ROW ){
this.sabriEntity=sabriEntity;
this.RATING_ID_COL = RATING_ID_COL;
this.RATING_ID_ROW= RATING_ID_ROW;

}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    相关资源
    最近更新 更多