2017-09-12 7 views
0

これは重複したリンクされた質問をすることは絶対にありません!JPA spring-bootで変更された列のみを保存する方法

私の問題は、JPAがすべてのフィールドを保存しようとしていることです。

エンティティ:

@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なし)
update tkmstp set tkudssky = ?, tkevol = ?, tkgdk =?ここで、tkknnr =?そしてtkslsk =?そしてtknr =

エラー:
ます。java.sql.SQLException:[SQL0407]列または変数TKLV5DATに許可されていないNULL値。すべて事前に

おかげで...

はJPAの設定Application.properties:

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 
+0

更新前のTKLV5DATは何ですか?それはヌルであったか、値を含んでいましたか? – PaulNUK

+0

@PaulNUKそれはnullですが、奇妙なことに私は知っていますが、これはJPAがこれまでに使用されていなかったためです。 –

+0

これらのフィールドを更新することはありませんか?あるいは時にはそれらを更新したいのですか? –

答えて

0

IMO、これは許されてはならないし、どちらかのフィールドは一時、すべての時かあれば保存されませんORMレイヤーを使用する場合は、オブジェクトの完全性が保証されるようにオブジェクトをすべてのフィールドとともに保存する必要があります。だからあなたが望むものを達成する唯一の方法は、Expliciteの更新ステートメントを使うことです。

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(); 

もう1つの可能性は、DBMS-Meansを使用して1つの直接更新を使用して、TKLV5DATを正しいデフォルト値に設定することです。肯定的な副作用は、DBMS-ChecksとJPA-Checksが同じである可能性があります。

0

ロード時に列の値がNULLであるように見えるため、最も侵襲的でない修正は、データベースの列をNULL可能にすることです。