java - JPA - 无法获取在一对一关系中生成的主键

标签 java hibernate jpa spring-data-jpa one-to-one

我正在尝试为以下数据库表创建 JPA 映射: enter image description here

字段 ID_CODA、ID_MOVMENT 和 ID_INFORMATION 是由数据库中的序列生成的,我想在一个事务中将整个 CODA 对象持久保存到数据库中。

这是我已经完成的操作:

@Entity
@Table(name = "CODA_TEST")
public class CodedAccountStatement implements Serializable {

    @Id
    @Column(name = "ID_CODA")
    @SequenceGenerator(name = "seq_coda", sequenceName = "seq_coda", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_coda")
    private long identifier;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "statement")
    private List<MovementRecord> movements;

    public void addMovement(MovementRecord movementRecord) {
        if(this.movements == null) {
            this.movements = new ArrayList<>();
        }
        movementRecord.setStatement(this);
        this.movements.add(movementRecord);
    }
@Entity
@Table(name = "CODA_ARTICLE_MOUVEMENT_TEST")
@IdClass(MovementRecordIdentifier.class)
public class MovementRecord implements Serializable {

    @Id
    @Column(name = "ID_MOUVEMENT")
    @SequenceGenerator(name = "seq_coda_article_mouvement", sequenceName = "seq_coda_article_mouvement",allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_coda_article_mouvement")
    private long movementId;

    @Id
    @ManyToOne
    @JoinColumn(name = "ID_CODA", referencedColumnName = "ID_CODA")
    private CodedAccountStatement statement;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "movementRecord")
    private DomiciliationRecord domiciliationRecord;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "movementId")
    private List<InformationRecord> informationRecords;

    public void setDomiciliationRecord(DomiciliationRecord domiciliationRecord) {
        domiciliationRecord.setMovementRecord(this);
        this.domiciliationRecord = domiciliationRecord;
    }

    public void addInformationRecord(InformationRecord informationRecord) {
        if(this.informationRecords == null) {
            this.informationRecords = new ArrayList<>();
        }
        informationRecord.setMovementId(this);
        this.informationRecords.add(informationRecord);
    }

@Entity
@IdClass(InformationRecordIdentifier.class)
@Table(name = "CODA_ARTICLE_INFORMATION_TEST")
public class InformationRecord implements Serializable {

    @Id
    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "ID_MOUVEMENT", referencedColumnName = "ID_MOUVEMENT"),
            @JoinColumn(name = "ID_CODA", referencedColumnName = "ID_CODA")
    })
    private MovementRecord movementId;

    @Id
    @Column(name = "ID_INFORMATION")
    @SequenceGenerator(name = "seq_coda_article_information", sequenceName = "seq_coda_article_information", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_coda_article_information")
    private long informationId;
@Entity
@IdClass(MovementRecordIdentifier.class)
@Table(name = "CODA_ARTICLE_MOUVEMENT_DOM_TEST")
public class DomiciliationRecord implements Serializable {

    @Id
    @Column(name = "ID_MOUVEMENT")
    private long movementId;

    @Id
    @Column(name = "ID_CODA")
    private long statement;

    @OneToOne
    @JoinColumns({
            @JoinColumn(name = "ID_MOUVEMENT"),
            @JoinColumn(name = "ID_CODA")
    })
    private MovementRecord movementRecord;

以下是我如何使用 Spring Data Jpa 接口(interface)持久保存该对象:

    private final CodedAccountStatementRepository repository;

    @Transactional
    public void save() {
        CodedAccountStatement statement = new CodedAccountStatement();

        MovementRecord movementRecord = new MovementRecord();
        movementRecord.setDomiciliationRecord(new DomiciliationRecord());
        movementRecord.addInformationRecord(new InformationRecord());

        statement.addMovement(movementRecord);

        LOGGER.info("Coda to save = {}", statement);
        repository.save(statement);
    }

正如您从日志中看到的:

insert into CODA_TEST (ID_CODA) values (?)
binding parameter [1] as [BIGINT] - [140]
insert into CODA_ARTICLE_MOUVEMENT_TEST (ID_MOUVEMENT, ID_CODA) values (?, ?)
binding parameter [1] as [BIGINT] - [3400]
binding parameter [2] as [BIGINT] - [140]
insert into CODA_ARTICLE_INFORMATION_TEST (ID_INFORMATION, ID_MOUVEMENT, ID_CODA) values (?, ?, ?)
binding parameter [1] as [BIGINT] - [127]
binding parameter [2] as [BIGINT] - [3400]
binding parameter [3] as [BIGINT] - [140]
insert into CODA_ARTICLE_MOUVEMENT_DOM_TEST (ID_MOUVEMENT, ID_CODA) values (?, ?)
binding parameter [1] as [BIGINT] - [0]
binding parameter [2] as [BIGINT] - [0]
ORA-02291: integrity constraint (EGCA1.FK_CODA_ARTICLE_MOUVEMENT_DOM_CODA_TEST) violated - parent key not found

已经为每个实体正确生成了标识符,但 Hibernate 没有为 DomiciliationRecord 主键提供正确的值(我们有 0, 0)...

最佳答案

根据@Augusto 评论,我已经这样更改了我的数据库表: enter image description here

这降低了我的问题的复杂性,并且映射现在变得微不足道。

关于java - JPA - 无法获取在一对一关系中生成的主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56007650/

相关文章:

java - 使用单线程调度程序时,RxJava mergeLatest 的单元测试挂起

java - 无法从 @Transaction 中具有关系的两个表中删除

java - python 和 Java 中 while 循环中的表达式与赋值?

java - Android - 两个类共享首选项

mysql - 从服务器成功接收到的最后一个数据包是在 43417 秒前

java - 映射同类关系 - 延续

java - 无法提交 JPA 事务 : Transaction marked as rollbackOnly

java - 组织.postgresql.util.PSQLException : ERROR: null value in column "category_id" violates not-null constraint

java - 如何重写实现接口(interface)的类中的方法

java - 具有相同数据/列但表名不同的 Hibernate 和表