Pertama-tama, saya tidak yakin apakah ini permintaan caching atau tidak mengisi bidang.

Saya memiliki entitas bernama CmsRegions, yang berisi berikut ini:

public class CmsRegions extends Model implements Serializable {
       
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 100)
    @Column(name = "name")
    private String name;
    
    @Lob
    @Size(max = 65535)
    @Column(name = "description")
    private String description;
    
    @Size(max = 2)
    @Column(name = "lang")
    private String lang;
    
    @Size(max = 2)
    @Column(name = "locale")
    private String locale;
    
    @Basic(optional = false)
    @NotNull
    @Column(name = "is_active")
    private short isActive;
    
    @Column(name = "parent_id")
    private Integer parentId;
        
    @Basic(optional = false)
    @Column(name = "created", insertable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date created;
    
    @Basic(optional = false)
    @Column(name = "modified", insertable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date modified;


    ...getters and setters etc...
}

Saya memiliki panggilan repositori dasar untuk mengambil entitas sebagai:

@NoRepositoryBean
public interface BaseCmsRepository<T extends Serializable> extends JpaRepository<T, Long> {
    
    @Query("SELECT a FROM #{#entityName} a WHERE a.id = :id")
    List<T> getById(
            @Param("id") Integer id
    );
    

Ketika saya menyimpan entitas, itu disimpan ke database dengan baik ke dalam tabel berikut:

CREATE TABLE `cms_regions` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `description` text,
  `lang` char(2) DEFAULT NULL,
  `locale` char(2) DEFAULT NULL,
  `is_active` tinyint unsigned NOT NULL DEFAULT '0',
  `parent_id` int unsigned DEFAULT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

Bidang created dan modified disetel dengan baik seperti yang diharapkan, tetapi entitas yang dihasilkan yang saya dapatkan dari tindakan penyimpanan saya, memiliki nilai NULL untuk tanggal yang dibuat dan diubah.

Saya menjalankan tes - ID penyisipan terakhir saya adalah 31, jadi saya menambahkan kode berikut ke pengontrol saya:

    cmsService.saveRegion(region); // save entity

    CmsRegions  testreg1 = cmsService.getRegion(1);
    CmsRegions  testreg2 = cmsService.getRegion(region.getId());
    CmsRegions  testreg3 = cmsService.getRegion(30);
    CmsRegions  testreg4 = cmsService.getRegion(32);  // currently saved entity new ID (32)

Saat melakukan ini - testreg1 berisi tanggal yang dibuat dan dimodifikasi sebagai objek Tanggal seperti yang diharapkan. testreg2 berisi nilai nol (region.getId() = 32 pada saat ini). testreg3 berisi objek Date untuk dibuat dan dimodifikasi.

Nilai akhir, testreg4 juga NULL. Penendangnya adalah, lain kali saya menjalankannya, testreg4 memiliki nilai di dalamnya untuk created dan modified. Tapi iterasi berikutnya, (33) di testreg2 sekali lagi NULL.

image of data in debug

Saya tidak tahu apakah ini masalah caching, atau apa. Tampaknya jika saya mencoba menarik nilai basis data sebelum panggilan selesai - BAHKAN meskipun data sekarang ada di basis data (dikonfirmasi dengan breakpoints) - bidang yang dihasilkan selalu nol. Jalankan berikutnya, mereka terisi.

Mengapa? Apa yang harus saya lakukan untuk mendapatkan nilai-nilai ini?

0
Barry Chapman 3 September 2020, 05:45

1 menjawab

Jawaban Terbaik

Saat menyimpan menggunakan JpaRepository#save atau metode ini pada antarmuka serupa, entitas dari database dikembalikan. Anda hanya dapat menggunakannya. Ini paling sering digunakan untuk mengisi id yang dihasilkan:

assertNull(entity.getId());
entity = entityRepository.save(entity);
assertNotNull(entity.getId());

Ini sedikit lebih kompleks ketika proses lain mengubah data dan konteks persistensi tidak disegarkan. Permintaan lain akan diperlukan saat itu. Anda dapat mengatasinya dengan menggunakan EntityManager#refresh dan meneruskan entitas yang ingin Anda "ambil kembali" dari database. Saat ini saya tidak tahu apakah mekanisme itu ada di spring-data-jpa.

1
Andronicus 3 September 2020, 02:58