如何在JPA spring-boot中仅保存更改的列

时间:2017-09-12 11:02:59

标签: hibernate jpa spring-boot spring-data-jpa

这与重复的链接问题绝对没有任何关系!

我的问题是JPA正在尝试保存所有字段,即使它没有更改它们,这会在db2上为我遗留一些东西。

实体:

@Data  // Auto getter and setters by lombok
@Entity
@IdClass(TkmstpId.class)
@Table(name="TKMSTP")
public class Tkmstp implements Serializable { 
    // DMD column: Tkslsk: decimal(2)
    @Id
    @Column(name="TKSLSK")
    private Long slskNr;
    // DMD column: Tkknnr: decimal(7)
    @Id
    @Column(name="TKKNNR")
    private Long kundenr;
    // DMD column: Tknr: decimal(7)
    @Id
    @Column(name="TKNR")
    private Long tankNummer;
    // DMD column: Tkstat: decimal(1)
    @Column(name = "TKEVOL")
    private Long estAarsForbrug;
    @Column(name = "TKGDK")
    private Long gKode;
    @Column(name = "TKUDSSKY")
    private String udskrivKortJn;
    @Column(name="TKLV5DAT")
    private java.sql.Date leveringsDato_tklv5dat;
    // DMD column: Tkudssky: char(1)

}

处理:

TkmstpId id = new TkmstpId();
                id.setKundenr(Long.parseLong(customer.getAccountNumber()));
                id.setSlskNr(1L);
                id.setTankNummer(customer.getContainerId());
                Tkmstp container = tkmstpRepository.getOne(id);
                if (container != null) {
                    boolean changed = false;
                    if (container.getEstAarsForbrug() == null || container.getEstAarsForbrug() == 0L) {
                        changed = setContainerEstimatedValues(container, customer);
                    } else if (container.getGKode() != 5L && container.getGKode() != 6L) {
                        changed = setContainerEstimatedValues(container, customer);
                    }
                    if (changed) {
                        tkmstpRepository.save(container);
                        System.out.println("updated container info on: customer: " + id.getKundenr() + " and container: " + id.getTankNummer());
                    }
                }

SQL生成:

Hibernate: update tkmstp set tklv5dat=?, tkudssky=?, tkevol=?, tkgdk=? where tkknnr=? and tkslsk=? and tknr=?

SQL我想要(没有tklv5dat)
更新tkmstp设置tkudssky =?,tkevol =?,tkgdk =?哪里tkknnr =?和tkslsk =?和tknr =?

错误:
java.sql.SQLException:[SQL0407]列或变量TKLV5DAT中不允许空值。

先谢谢所有人......

Application.properties jpa设置:

 spring.jpa.database-platform=org.hibernate.dialect.DB2Dialect
 spring.jpa.hibernate.ddl-auto = false spring.jpa.show-sql=true 
 spring.datasource.driver-class-name=com.ibm.as400.access.AS400JDBCDriver

2 个答案:

答案 0 :(得分:0)

imO这不能被允许,要么字段是瞬态的而根本不保存,要么使用ORM-Layer,对象必须与其所有字段一起保存,以确保对象的完整性得到保证。所以我认为实现你想要的唯一方法是使用明确的更新语句。

em.createQuery(
   "update tkmstp t 
       set t.tkudssky=:tkudssky, t.tkevol=:tkevol, t.tkgdk=:tkgdk 
       where t.tkknnr=:tkknnr and t.tkslsk=:tkslsk and t.tknr=:tknr")
   .setParameter(":tkudssky",container.tkudssky)
   .setParameter(":tkevol",container.tkevol)
   .setParameter(":tkgdk",container.tkgdk)
   .setParameter(":tkknnr",container.tkknnr)
   .setParameter(":tkslsk",container.tkslsk)
   .setParameter(":tkudssky",container.tkudssky)
   .executeUpdate();

另一种可能性是使用DBMS-Means直接使用一个更新来将TKLV5DAT设置为正确的默认值。积极的副作用是,DBMS-Checks和JPA-Checks可能是相同的。

答案 1 :(得分:0)

在加载时,列值似乎为null,因此最小的修复是使数据库上的列可以为空。