我在使用 Spring、Hibernate 和 JPA 的 Web 应用程序中遇到一些问题。问题是内存消耗非常高,随着时间的推移,内存消耗会增加,而且似乎永远不会减少。它们很可能源于 EntityManager 的错误使用。我已经四处寻找,但还没有找到确定的东西。
我们使用的 DAO 都扩展了以下 GenericDAO,其中注入了我们唯一的 EntityManager:
public abstract class GenericDAOImpl<E extends AbstractEntity<P>, P> implements
GenericDAO<E, P> {
@PersistenceContext
@Autowired
private EntityManager entityManager;
[...]
Run Code Online (Sandbox Code Playgroud)
使用通用 DAO 是因为它具有通过 ID 等获取实体的方法,这在所有约 40 个 DAO 中实现起来会很痛苦。
EntityManager 通过以下方式配置为 Spring bean:
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="entityManager" factory-bean="entityManagerFactory"
factory-method="createEntityManager" scope="singleton" />
Run Code Online (Sandbox Code Playgroud)
我认为最大的问题是使用这个共享的 EntityManager 来处理所有事情。在服务类中,我们对需要事务的方法使用@Transactional 注释。这会根据我读取的内容自动刷新 EntityManager,但与清除不同,所以我猜对象仍在内存中。
我们注意到每天都会在数据库中自动导入数据后内存会增加(大约 …
我遇到了 JPA 问题,无法解决。
我在 glassfish 3+ 上部署我的 web 应用程序,当应该构建 EntityManagerFactory 时,它总是抛出异常:
javax.persistence.PersistenceException: [PersistenceUnit: lab4] Unable to build EntityManagerFactory
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪:
javax.faces.el.EvaluationException: javax.persistence.PersistenceException: [PersistenceUnit: lab4] Unable to build EntityManagerFactory
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at …Run Code Online (Sandbox Code Playgroud) 在 Java SE 环境中运行的桌面应用程序(没有 DI,除了 JPA 之外没有框架,纯 Java)最好为持久层中的每个操作创建一个新的 EntityManager 或者在整个过程中共享 EntityManager 的单个实例持久层?
两种解决方案的利弊?
更新:
该应用程序使用一个只有一个架构的数据库实例。
运行我的 jar 时出现此异常。
java.lang.IllegalStateException: Conflicting persistence unit definitions
for name 'hibernateUnit': file:/D:/Assignment.jar, file:/D:/Assignment.jar
Run Code Online (Sandbox Code Playgroud)
我的持久性.xml
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="hibernateUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>EventImpl</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format.sql" value="true"/>
<property name="hibernate.connection.driver_class" value="${db.driver.name}"/>
<property name="hibernate.connection.url" value="${db.url.value}"/>
<property name="hibernate.connection.username" value="${db.user.name}"/>
<property name="hibernate.connection.password" value="${db.user.password}"/>
</properties>
</persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)
我的 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:property-placeholder location="db.properties"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/> …Run Code Online (Sandbox Code Playgroud) 我有一个 SQL 脚本文件,它删除并重新创建各种表,并将各种记录插入到这些表中。该脚本在 SQL 查询控制台中执行时运行良好,但我需要它由实体管理器执行。
关于我如何能够做到这一点的任何想法?
谢谢,
H
我正在测试新的 JPA 2.1 类型转换器。我想避免将 NULL 字符串值存储在旧数据库中,因为它们是不允许的。所以我定义了以下转换器:
@Converter(autoApply=true)
public class CString implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String str) {
if( str == null || str.length() == 0 ) {
return " ";
} else {
return str;
}
}
@Override
public String convertToEntityAttribute(String str) {
if( str == null || str.length() == 0 || str.equals(" ") ) {
return null;
} else {
return str;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果字符串属性为 NULL,则应将其转换为空格字符,但当属性为 NULL 时,不会执行转换器方法。
我正在尝试 hibernate-jpa-2.1-api (1.0.0.Final) 和 hibernate-entitymanager (4.3.6.Final)。
有没有符合 …
我正在开发一个 spring mvc 项目,我想转换我在我在 spring mvc 3 上工作时编写的 applicationContext.xml 中的 jpa 配置,现在我想转移到 spring Mvc 4 并编写我所有的 Jpa仅使用 Java 注释的配置有人可以帮助我
这是我的 applicationContext 文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/db_adpub"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="datasource"></property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
<property name="persistenceUnitName" value="adpub"></property>
</bean>
<bean id="transactionManager" …Run Code Online (Sandbox Code Playgroud) 我最近创建了一个 Web 服务,它使用 Java 中的静态方法从数据库中获取项目列表。
Web 服务完美运行并将 JSON 返回给调用者。但是,它只能工作一次。如果您尝试刷新或发出新请求,我会收到EntityManagerFactory is closed错误消息。
Web Service 类如下所示:
public class WebService extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//obtain the list of vehicles from the database
List<Vehicle> vehicles = ExecuteVehicle.getVehicleList();
//create the Gson object and generate the Json
Gson gson = new Gson();
JsonElement element = gson.toJsonTree(vehicles, new TypeToken<List<Vehicle>>(){}.getType());
//send the list of vehicles
JsonArray jsonArray = element.getAsJsonArray();
resp.setContentType("application/json");
resp.getWriter().print(jsonArray);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,车辆列表正在使用该ExecuteVehicle.getVehicleList()方法进行填充。 …
在我的项目中,我有一个 User 实体和一个 UserRole 实体。根据我的数据库设计,一个用户可以扮演多个角色,一个角色可以关联多个用户。我在系统中的用户角色是 USER 和 ADMIN。
需要将用户角色存储在表中,并且当用户在其相关表中持久化时需要引用它们。
但是,根据我实现的代码,每次将用户插入数据库时,记录也会插入到用户角色表中。我需要的是将数据插入到用户表和连接表中。
这些是我的实体。
用户:
@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, updatable= false)
private Long id;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(name = "password_hash", nullable = false)
private String passwordHash;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = …Run Code Online (Sandbox Code Playgroud) 有一些示例可以处理多个数据源:
@Inject
@DataSource("users")
AgroalDataSource dataSource1;
@Inject
@DataSource("inventory")
AgroalDataSource dataSource2;
Run Code Online (Sandbox Code Playgroud)
但他们不使用 EntityManager。是否有可能得到类似的东西:
@Inject
@DataSource("users")
EntityManger em1;
@Inject
@DataSource("inventory")
EntityManger em2;
Run Code Online (Sandbox Code Playgroud)
谢谢。
entitymanager ×10
java ×6
jpa ×6
hibernate ×5
spring ×3
drop-table ×1
jpa-2.1 ×1
many-to-many ×1
persistence ×1
quarkus ×1
spring-mvc ×1
sql ×1
sql-scripts ×1
web-services ×1