java - 合并不会在 JPA 中更新

标签 java spring-mvc jpa spring-data-jpa

拥有这个实体类:

@Entity
@Table(name="t_period")
public class Period {

    @Id
    @GeneratedValue(strategy = SEQUENCE, generator = "periodSeq")
    @Column(name = "PERIOD_ID", unique = true, nullable = true)
    @SequenceGenerator(name = "periodSeq", sequenceName = "seq_period", allocationSize=1)
    private Long periodId;

    @OneToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumn(name = "CLASS_GROUP_ID", referencedColumnName = "ID")
    ClassGroup classGroup;

    @Column(name="PERIOD1")
    Integer period1;

    @Column(name="PERIOD2")
    Integer period2;

    ...
}

和..

/**
 * ProductGroup generated by Tomasz Borowiec
 */
@SuppressWarnings("serial")
@Entity
@Table(name = "T_CLASS_GROUP", uniqueConstraints = @UniqueConstraint(columnNames = "KEY"))
@SequenceGenerator(name = "seqCLASS_GROUP", sequenceName = "SEQ_CLASS_GROUP")
public class ClassGroup implements java.io.Serializable {

    private Long id;
    private String key;


    @Id
    @Column(name = "ID", unique = true, nullable = false, precision = 38, scale = 0)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqCLASS_GROUP")
    public Long getId() {
        return this.id;
    }

...

}

DAO

public class PeriodDaoImpl extends JpaDaoSupport implements PeriodDao {
       ...
    @Override
    public Period saveOrUpdate(Period period) throws Exception {

        if (period.getPeriodId() == null &&
                find(period.getClassGroup()) == null) {
            getEntityManager().persist(period);

        } else {

            period = getEntityManager().merge(period);
        }

        return period;
    }
        ...
}

Junit 中的这段代码用于测试 DAO:

    ClassGroup classGroup = classGroupDao.findById(1);

    Period period = new Period();
    period.setClassGroup(classGroup)
    period.setPeriod1(1);

    period = periodDao.saveOrUpdate(period);
    period.setPeriod1(2);
    period = periodDao.saveOrUpdate(period);

我在第二次更新时遇到此错误,执行合并,而不是持久

在数据库级别,我为对象 classGroup 设置了一个唯一的键:

CREATE TABLE t_period
(
  period_id number(38) not null,
  class_group_id number(38) not null,
  period1 number,
  period2 number,
  CONSTRAINT pk_period PRIMARY KEY        (period_id),
  CONSTRAINT fk_class_group   FOREIGN KEY (class_group_id) REFERENCES t_class_group(id),
  CONSTRAINT uk_class_group UNIQUE        (class_group_id)
);

ORA-00001:违反唯一约束 (ENV_ECAT.UK_CLASS_GROUP)

最佳答案

使用此代码,persist 永远不会执行,因为 find(period.getClassGroup()) 永远不会返回 null。这意味着 merge() 被调用两次,但它不会返回 id,所以我认为这就是它尝试插入同一对象两次的原因。

因此,尝试从 if 语句中删除 find(...) 看看它是否有效。

if (period.getPeriodId() == null) {
    getEntityManager().persist(period);
}

如果它确实有效,您必须想出不同的条件来分支对 merge()persist() 的调用。

关于java - 合并不会在 JPA 中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26971454/

相关文章:

java - 如何检查两个字符串数组是否相同

java - 具有并发(多进程)访问权限的 Java 中的文件数据库

java - Maven 更新项目后项目结构发生了变化,源文件夹的包含和排除模式也发生了变化

java - 使用带有 'SELECT OBJECt(var) FROM EntityName var 的 @NamedQuery 实现查询

java - Eclipse中的Java项目和Eclipse本身有什么区别?

java - Sprite 围绕一个点旋转 Andengine/Java

javascript - 由于数据量巨大,Javascript 变得无响应和停止

java - 请求中包含列表的映射对象 - Spring MVC

java - 如何使用 Spring+JPA 更新来自 Play Framework 2.0 表单的对象?

java - JPA 与 EclipseLink : Decoding charset issue