简体   繁体   中英

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 .

A REST call is made, within that call I set a Device to be InUse to 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()) . 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. This leads me to believe that it is somehow caching this.

In the hibernate logs I see

  • The parent object which holds a list of devices being loaded from hibernate
  • (This is where the device should then be updated with inUse = true)
  • Continues to load other details from Hibernate for Lists of @Entity 's from the parent but never updates the device...

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

# 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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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