我正在使用Hibernate和JPA EntityManager,而不是Hibernate会话。大多数人似乎建议为每笔交易使用新的EntityManager,这就是我正在做的事情。
所以,我连续创建了10000个新实体。堆使用率在第一次迭代时约为90 MB,在最后一次迭代时约为5 GB。
这是我的迭代代码:
Session session = Core.getDatabase().createEntityManager().unwrap(Session.class);
Query query = session.getNamedQuery("Account.getAllIds");
query.setReadOnly(true);
query.setFetchSize(100);
ScrollableResults accounts = query.scroll(ScrollMode.FORWARD_ONLY);
EntityManager entityManager = Core.getDatabase().createEntityManager();
entityManager.getTransaction().begin();
while (accounts.next()) {
int id = (int) accounts.get(0);
Account account = entityManager.getReference(Account.class, id);
Core.getDatabase().persist(new AccountTest(account));
changes++;
}
entityManager.close();
accounts.close();
session.close();
我的持久性功能:
public class Database
{
private final EntityManagerFactory entityManagerFactory;
public Database(String host, String database, String user, String password)
{
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("javax.persistence.jdbc.url", "jdbc:mysql://" + host + ":3306/" + database);
properties.put("javax.persistence.jdbc.user", user);
properties.put("javax.persistence.jdbc.password", password);
entityManagerFactory = Persistence.createEntityManagerFactory("default", properties);
}
public EntityManager createEntityManager()
{
return entityManagerFactory.createEntityManager();
}
public void persist(Object... objects)
{
EntityManager entityManager = createEntityManager();
entityManager.getTransaction().begin();
for (Object object : objects) {
entityManager.persist(object);
}
entityManager.getTransaction().commit();
entityManager.clear();
entityManager.close();
}
}
所以我遍历所有帐户实体(10k,但由于滚动功能而使用Hibernate Session),并希望为每个帐户创建一个新的AccountTest。
答案 0 :(得分:4)
问题是您是否一直打开第一个EntityManager
,而只清除和关闭仅用于保留一个项目的另一个EntityManager
。
最后,您在第一个EntityManager
中加载了所有帐户实体。