我在JavaEE项目中使用Spring + Hibernate。
在这个项目中,用户可以上传我应该导入我的数据库的XLS文件。在导入之前,我必须验证此文件,检查其数据库中的其他实体的完整性。所以我或多或少有以下几点:
// The importer
@Component("importer")
public class Importer {
@Autowired
FirstDAO firstDao;
@Autowired
SecondDAO secondDao;
// Read the file and open it (65.000 lines for example)
public void validate() {
foreach line in the file {
firstDAO.has(line[col1]);
secondDao.has(line[col2]);
}
// It stores the valid objects in a List and persist them at the end
}
}
// The DAO
@Repository
public class FirstDao {
@PersistenceContext
protected EntityManager entityManager;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public boolean has(String name) {
List<Object> result = entityManager.createQuery( from FIRST_TABLE where name = :name)
.setParameter("name", name)
.getResultList();
if (result.size > 0) return true;
else return false;
}
}
// The PersistenceContext/Hibernate configuration
<!-- Data Source -->
<jee:jndi-lookup id="myDS" jndi-name="jdbc/my-DS" cache="true" proxy-interface="javax.sql.DataSource" />
<!-- Entity Manager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property value="classpath:META-INF/my_persistence.xml" name="persistenceXmlLocation"/>
<property name="dataSource" ref="myDS"/>
<property name="persistenceUnitName" value="myPersistenceUnit" />
<!--
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
</property>
</bean>
记录应用程序后,我注意到了:
我读过关于entityManager
的事情,但我仍然不知道我做得对,所以:
Stateless Persistence Context
。我怀疑内存泄漏可能存在。也许Hibernate在PersistenceContext中记录了很多对象。如何在验证时告诉实体管理器不缓存这些人?提前致谢。
答案 0 :(得分:0)
首先,除非你有一个很好的理由,否则你不应该一行一行。即使数据大小比你的内存大,你应该一次做1000行或类似的东西,但绝对不是一个接一个。 因为数据库使用最重要的优化之一是减少数据库命中数。
其次,您不应仅仅检查数据是否存在。 您应该使用基本的“选择计数”查询。通过这种方式,您将摆脱所有的东西,如消耗IO来读取数据并通过网络将数据检索到您的服务器,并花费内存来获取该列表中的对象数量。
如果您将使用我的第一个建议并检查现有的记录,而不是一次只检查1000个记录,那么您可以只选择名称而不是所有行。
据我所知,你正在使用数据源,如果正确配置了最大连接数等,你不必担心数据库连接的数量。