【问题标题】:EntityManager is blocking the database triggerEntityManager 正在阻止数据库触发器
【发布时间】:2021-12-19 11:13:43
【问题描述】:

在我准备的场景中,jpa 锁定了新记录。因此,数据库中的触发器没有被激活。我该如何解决这种情况?

当我创建客户时,代码由触发器分配给客户。但是,由于在此过程中创建的记录被锁定,因此触发器没有被激活。

@Entity
public class Customer {
    @Id
    @Column
    private int id;
    @Column
    private String name;
    @Column
    private String address;
    @Column
    private int personRef;
    @Column
    private int customerCode; //db trigger updated
}

@Entity
public class Person {
    @Id
    @Column
    private int id;
    @Column
    private String name;
    @Column
    private String surname;

}


public class CustomerDTO {

    private int id;
    private String name;
    private String address;
    private int personRef;
    private PersonDTO person;
}


public class PersonDTO {
    private int id;
    private String name;
    private String surname;

}

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer>{
    
}

@Service
public class CustomerService{
    @Autowired
    private final CustomerRepository customerRepository;
    @Autowired
    private final PersonService personService;
    
    @Transactional(rollbackFor = {Exception.class})
    public int control(CustomerDTO customerDTO){
         Customer customer =  customerRepository.findById(customerDTO.getId());
         if(customer == null){
             ModelMapper mapper = new ModelMapper();
              customer =  mapper.map(customer,Customer.class);
             customerRepository.saveAndFlush(customer);
             Person person = mapper.map (customer.getPerson(),Person.class);
             personService.saveAndFlush(person);
             customer =  customerRepository.findById(customerDTO.getId());
             customer.setPersonRef(person.getId());
             customerRepository.saveAndFlush(customer);
             return customer.getCustomerCode;
             
         }
         return customer.getCustomerCode();
    
    }
    
}

【问题讨论】:

  • 我不明白你的问题。为什么你认为有东西被锁定了? SaveAndFlush 不会从数据库中读取记录,因此 customerCode 不包含您在触发器中设置的值
  • 我用 saveAndFlush 保存的记录用数据库端的触发器更新。当我第二次尝试提取刚刚使用 findById 创建的记录时,触发器更新的列显示为空。我认为 Hibernate 正在锁定我创建的记录。我找不到如何解除这个锁。
  • No findById 从一级缓存返回实体。您必须调用 refresh 才能从数据库中获取实体 newley
  • jpa 该怎么办。

标签: hibernate jpa spring-data-jpa


【解决方案1】:

问题是触发器在数据库中运行,而 Hibernate 不知道这一点。

所以你必须在触发器运行后刷新实体:

@Service
public class CustomerService{
    @Autowired
    private final CustomerRepository customerRepository;
    @Autowired
    private final PersonService personService;
    @Autowired
    private EntityManager em;

    @Transactional(rollbackFor = {Exception.class})
    public int control(CustomerDTO customerDTO){
         Customer customer =  customerRepository.findById(customerDTO.getId());
         if(customer == null){
             ModelMapper mapper = new ModelMapper();
              customer =  mapper.map(customer,Customer.class);
             customerRepository.saveAndFlush(customer);
             Person person = mapper.map (customer.getPerson(),Person.class);
             personService.saveAndFlush(person);
             customer =  customerRepository.findById(customerDTO.getId());
             customer.setPersonRef(person.getId());
             customerRepository.saveAndFlush(customer);

             // Reload the data from the database
             em.refresh(customer);

             return customer.getCustomerCode;
             
         }
         return customer.getCustomerCode();
    
    }
    
}

【讨论】:

  • 是否有通用的解决方案,或者对于类似情况我应该遵循相同的方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 2012-08-06
  • 1970-01-01
相关资源
最近更新 更多