2016-08-12 41 views
1

在某些時候我的應用程序停止保存@Entityboolean值時,由我的Repository保存。Spring JPA /休眠沒有更新到數據庫更改布爾的@Entity在保存

A REST致電,在該呼叫中,我設置DeviceInUse爲真。

 device.setInUse(inUse); 
     Device savedDev = deviceRepository.save(device); 

     Logger.debug("Device after save isInUse() " + savedDev.isInUse()); 
     Thread.sleep(5000); 

     Device dbDev2 = deviceRepository.findOne(device.getSerial()); 
     Logger.debug("Device again from db for isInUse() " + dbDev2.isInUse()); 

的這個輸出是true爲被保存兩個裝置併發出deviceRepository.findOne(device.getSerial())時。問題是,當我進入數據庫,並實際觀看它沒有被更新的記錄。

我打開休眠調試日誌記錄,我無法看到更新正在對設備進行。當我保存其他@Entity的,我可以看到在日誌中Hibernate查詢。這使我相信它以某種方式緩存了這一點。

在休眠日誌我看到

  • 從休眠
  • (這是該裝置應,然後用INUSE =真被更新)
  • 被加載保持的設備的列表的父對象繼續加載從休眠等細節從父@Entity的列表,但從來沒有更新設備...

Q問題

我想知道可能是什麼原因造成的?

休息控制器

@RestController 
@Transactional(propagation = Propagation.REQUIRED) 
public class HomeController { 

    @Autowired 
    private DeviceRepository deviceRepository; 

    /** 
    * Default index 
    * 
    * @return 
    */ 
    @RequestMapping(value = "/") 
    public String index() { 
     return "index"; 
    } 


    @RequestMapping(value = "runTestRun", method = RequestMethod.POST) 
    public ResponseEntity<String> runTestRun(@RequestBody String jsonObject) throws Exception { 

     ..... 
      setDevicesInUse(testRun.getDevices(), true); 
     ..... 
    } 

private void setDevicesInUse(Set<Device> devices, boolean inUse) throws InterruptedException { 
    for (Device device : devices) { 
     Logger.debug("Marking Device " + device.getSerial() + " " + device.getReadableName() + " InUse to " + inUse); 

     Device dbDev = deviceRepository.findOne(device.getSerial()); 
     Logger.debug("Device before change checking isInUse() " + dbDev.isInUse()); 
     dbDev.setInUse(inUse); 
     Logger.debug("Device after setting isInUse() " + dbDev.isInUse()); 

     device.setInUse(inUse); 
     Device savedDev = deviceRepository.save(device); 

     Logger.debug("Device after save isInUse() " + savedDev.isInUse()); 
     Thread.sleep(2000); 

     Device dbDev2 = deviceRepository.findOne(device.getSerial()); 
     Logger.debug("Device again from db for isInUse() " + dbDev2.isInUse()); 
     Thread.sleep(2000); 
    } 
} 

Application.properties

# DataSource settings: set here your own configurations for the database 
# connection. 
spring.datasource.url: jdbc:mysql://localhost/xxx 
spring.datasource.username=xxx 
spring.datasource.password=xxx 
spring.datasource.driverClassName=com.mysql.jdbc.Driver 

# Keep the connection alive if idle for a long time (needed in production) 
spring.datasource.testWhileIdle = true 
spring.datasource.validationQuery = SELECT 1 

# Show or not log for each sql query 
spring.jpa.show-sql = true 

# Hibernate ddl auto (create, create-drop, update) 
spring.jpa.hibernate.ddl-auto = update 

# Naming strategy 
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy 

# Use spring.jpa.properties.* for Hibernate native properties (the prefix is 
# stripped before adding them to the entity manager) 

# The SQL dialect makes Hibernate generate better SQL for the chosen database 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect 

# Use hibernates new generator mappings, this is used for the appium port using a TABLE generator 
spring.jpa.properties.hibernate.id.new_generator_mappings=true 

# Web server 
spring.data.rest.base-path=/api 
server.context-path=/api 
server.port=8082 

# TODO FOR DEBUG ONLY 
spring.thymeleaf.cache=false 
spring.freemarker.cache=false 
spring.groovy.template.cache=false 
spring.velocity.cache=false 
spring.mustache.cache=false 
server.session.persistent=true 
spring.h2.console.enabled=true 
spring.resources.cache-period=0 

我嘗試添加以下,但它並沒有區別

spring.jpa.properties.hibernate.cache .use_second_level_cache =假 spring.j pa.properties.hibernate.cache.use_query_cache =假

設備

@Data 
@Entity 
@Table(name = "device") 
public class Device { 


    private @Id String serial; 
    private boolean active; 
    private boolean inUse; 

    private @Version @JsonIgnore Long version; 

    private Device() { 
    } 
+0

經過粗略的一瞥,聞起來像是一個交易邊界問題。 – chrylis

+0

@chrylis我可以看到父對象正在加載形式休眠,然後它應該保存什麼都沒有發生。當我從存儲庫重新加載設備時,它顯示爲正在更新,但沒有休眠日誌顯示它實際設置設備,或者實際上從數據庫中檢索已保存的設備。 – ALM

回答

0

,因爲它是沒有完成因而該事務發送到DB中的問題涉及到跨國的設置。

@Transactional(propagation = Propagation.REQUIRED)