gpt4 book ai didi

java - 使用 Spring Data 在 eclipselink 中执行不带 SELECT 的 UPDATE

转载 作者:行者123 更新时间:2023-11-30 07:45:40 24 4
gpt4 key购买 nike

我正在使用 Spring Data(ver1.9) - JPA - EclipseLink(2.6.1) - Apache Tomcat。我想更新实体对象而不检查其是否存在。
示例实体,

@Entity
@Table(schema = "customSchema")
public class Person implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Integer id;

@Column(nullable = false, length = 60)
private String firstName;

public Person() {
this.id = null;
this.firstName = "";
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}
}

Spring 数据存储库示例,

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}

我执行的代码和生成的sql,

int id = 5; // This id is existing in my database.
Person Person = personRepository.findOne(id);
// SQL: One SELECT is executed. This is normal.

person.setFirstName("aNewFirstName");

personRepository.saveAndFlush(person);
// SQL: One SELECT is executed and then an update is executed.

persistence.xml,(为了线程安全禁用第 2 层缓存,it can be enabled selectively using @Cacheable annotation)

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="my_peristenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>package.to.entity.Person</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
</persistence-unit>
</persistence>

我的问题存在于 saveAndFlush 命令中。 EclipseLink 使用 SELECT sql 命令检查表行中的字段以确定哪些字段已更改。这有助于创建仅包含已编辑字段的更新命令。
删除命令也会发生同样的情况!

问题
有没有办法避免update(saveAndFlush)或delete(delete)命令的select sql执行?
如果我想更新表格的整行该怎么办?不检查哪些字段已更改?

我又看到了SO question与此类似,但此解决方案不适用于我的示例。我对 Person 实体使用了 @ExistenceChecking(value = ExistenceType.ASSUME_EXISTENCE) 注释,并且执行 saveAndFlush 命令时没有任何更改。

最佳答案

EclipseLink 有两个不同的 cache levels

第一个是持久性单元缓存。这是共享缓存 (L2) 或第 2 层缓存。该缓存是您禁用的缓存,

<shared-cache-mode>NONE</shared-cache-mode>

即使禁用它,您也可以使用 @Cacheable 注释显式使用它。

第二个是持久性上下文缓存。这是一个独立的缓存 (L1),为 EntityManager 内的操作提供服务。您的应用程序中存在此缓存级别。此缓存是避免 EclipseLink 提供程序出现此行为的关键。

您两次不同地调用存储库方法。要使用 L1 缓存,此调用必须使用相同的 EntityManager。在您的情况下,您使用不同的 EntityManager。下面的示例将相同的 EntityManger 用于两个不同的存储库调用。

@Service
public class MyEnityService {

@Transactional
public Boolean create() {
int id = 5; // This id is existing in my database.
Person Person = personRepository.findOne(id);
// SQL: One SELECT is executed. This is normal AND CACHED FROM YOUR ENTITY MANAGER.

person.setFirstName("aNewFirstName");

personRepository.saveAndFlush(person);
// SQL: ONLY ONE update is executed. NOTHING ELSE.

return true;
}
}

小心,@Transactional 注释不适用于 Controller 方法。您必须为此使用服务。

关于java - 使用 Spring Data 在 eclipselink 中执行不带 SELECT 的 UPDATE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33982897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com