Java Hibernate refresh()或getSingleResult()返回缓存实体(?)
我在Wildfly(JBoss)10上使用Hibernate2.1从数据库中获取实体。以下是实体的模型:Java Hibernate refresh()或getSingleResult()返回缓存实体(?),java,hibernate,jpa,caching,wildfly,Java,Hibernate,Jpa,Caching,Wildfly,我在Wildfly(JBoss)10上使用Hibernate2.1从数据库中获取实体。以下是实体的模型: @Entity @Table(name = "account") @NamedQuery(name = "Account.findAll", query = "SELECT a FROM Account a") public class Account implements Serializable { private
@Entity
@Table(name = "account")
@NamedQuery(name = "Account.findAll", query = "SELECT a FROM Account a")
public class Account implements Serializable {
private int id;
private double balance;
private double bonus;
@Id
public int getId() {
return this.id;
}
// Rest of the fields/setters/getters ommited
}
我实现了一个RESTAPI调用,它更新给定帐户的余额。帐户首先从数据库中检索、验证,然后通过MySQL中单独的bean管理事务更新余额。完成此操作后,我被要求对该帐户执行其他操作,我需要更新(新)余额。查找以下所附代码:
@Stateless
@Path("/financial")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FinancialApi {
@Inject private AccountBean accountBean;
@Inject private AccountBalanceBean accountBalanceBean;
@POST
@Path("/balance/add")
public Response addBalance(TransactionProperties properties) {
Account account;
try {
account = accountBean.get(properties.getAccountId());
validateAccount(account);
} catch (ValidationException ex) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
// Update balance
accountBalanceBean.updateBalance(account.getId(), properties.getAmount());
// Refresh from DB to retrieve updated balance
accountBean.refresh(account);
// Do stuff with refreshed account data here
return Response.ok().build();
}
}
处理帐户的“DAO”EJB
@Stateless
@LocalBean
public class AccountEJBean {
@PersistenceContext(unitName = "my-unit-name")
private EntityManager em;
public Account get(int id) {
try {
return (Account) em.createQuery("SELECT a FROM Account a WHERE a.id = :id")
.setParameter("id", id)
.setMaxResults(1)
.getSingleResult();
} catch (NoResultException ex) {
return null;
}
}
public void refresh(Account account) {
em.refresh(account);
}
}
以及使用bean管理的事务来更新帐户余额的EJB(严重减少)示例:
@Stateless
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class AccountBalanceEJBean {
@PersistenceContext(unitName = "my-unit-name")
private EntityManager em;
@Resource
private UserTransaction transaction;
public boolean updateBalance(int id, float price) {
try {
transaction.begin();
getUpdateQuery(id, price).executeUpdate();
transaction.commit();
} catch (Exception ex) {
transaction.rolloback();
}
}
}
这是我的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence">
<persistence-unit name="my-unit-name" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/jboss/datasources/SQLDatasource</jta-data-source>
<class>mypackage.Account</class>
<properties>
<property name="hibernate.generate_statistics" value="false"/>
<property name="hibernate.connection.useUnicode" value="true"/>
<property name="hibernate.connection.characterEncoding" value="UTF-8"/>
</properties>
</persistence-unit>
</persistence>
org.hibernate.ejb.HibernatePersistence
java:/jboss/datasources/SQLDatasource
我的包裹
在我尝试从数据库中刷新帐户数据之前,这一切都很好。此时,我尝试过的每个案例都会刷新帐户,没有任何问题,但帐户的数据不会得到更新。我仍在检索帐户最初检索时的“过时”数据。环顾四周一段时间后,我想这可能与Hibernate缓存机制有关。我尝试了以下方法:
get()
方法上的实体与EntityManager分离,并将refresh()
替换为get()
em.clear()
,然后再次使用get()
调用检索实体get()
方法的查询refresh()
方法覆盖的一级缓存有什么意义,以及它在分布式环境中是如何工作的
如果这有帮助,则注入的EntityManager实例是类org.jboss.as.jpa.container.TransactionScopedEntityManager
的实例
有什么想法吗
更新:我在第二个bean中复制了get()
代码,我们称之为AccountBean2,它也被注入到API类中。它现在似乎起作用了。我很有信心这是一个缓存问题,但我仍然不知道如何纠正最初的问题,所以问题仍然存在