简体   繁体   English

Spring JPA / Hibernate在保存时没有更新到DB以更改@Entity的布尔值

[英]Spring JPA/Hibernate not updating to DB for change of boolean for @Entity on save

At some point my application stopped saving the boolean value for a @Entity when being saved by my Repository . 在某些时候,我的应用程序在由我的Repository保存时停止保存@Entityboolean值。

A REST call is made, within that call I set a Device to be InUse to true. 进行REST调用,在该调用中,我将Device设置为InUse为true。

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

The output of this is true for both the device being saved and when issuing a deviceRepository.findOne(device.getSerial()) . 对于正在保存的设备和发出deviceRepository.findOne(device.getSerial()) ,输出都是true The problem is when I go into the database and actually view the record it is not being updated. 问题是当我进入数据库并实际查看记录时它没有被更新。

I turned on hibernate debug logging and I can not see the update being made to the device. 我打开了休眠调试日志,我看不到对设备进行的更新。 When I save other @Entity 's I can see the hibernate query in the logs. 当我保存其他@Entity ,我可以在日志中看到hibernate查询。 This leads me to believe that it is somehow caching this. 这让我相信它以某种方式缓存了这一点。

In the hibernate logs I see 在hibernate日志中,我看到了

  • The parent object which holds a list of devices being loaded from hibernate 包含从hibernate加载的设备列表的父对象
  • (This is where the device should then be updated with inUse = true) (这是应该使用inUse = true更新设备的位置)
  • Continues to load other details from Hibernate for Lists of @Entity 's from the parent but never updates the device... 继续从Hibernate加载来自父级的@Entity列表中的其他详细信息,但从不更新设备......

Question

I wanted to know what could be causing this? 我想知道是什么原因引起的?

Rest Controller 休息控制器

@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 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

I tried adding the following but it made no difference 我尝试添加以下内容,但没有任何区别

spring.jpa.properties.hibernate.cache.use_second_level_cache=false spring.jpa.properties.hibernate.cache.use_query_cache=false spring.jpa.properties.hibernate.cache.use_second_level_cache = false spring.jpa.properties.hibernate.cache.use_query_cache = false

Device 设备

@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() {
    }

这个问题与Transnational的设置有关,因为它没有完成交易,因此发送到数据库。

@Transactional(propagation = Propagation.REQUIRED)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM