jpa java.lang.IllegalStateException:没有可用的事务性EntityManager

20jt8wwn  于 2022-11-14  发布在  Java
关注(0)|答案(5)|浏览(187)

项目使用Hibernate(JPA),Spring和Maven.my实体和DAO放在一个单独的JAR中。
pom.xml:

<project ...>
    ...
    <artifactId>database</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.5.4-Final</version>
        </dependency>
    </dependencies>    
</project>

DAO:

public class AbstractDAO<T extends BaseEntity> implements GenericDAO<T> {

    private final Class<T> persistentClass;

    private EntityManager entityManager;

    public AbstractDAO(Class<T> entityClass) {
        super();
        this.persistentClass = entityClass;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    ...

    public void fooBar() {
       //Exception from this line
       Session session = getEntityManager().unwrap(Session.class);
       ...
    }

    ....

}
我有一个模块,它使用Spring。
pom.xml:

<project ...>
...
<artifactId>api</artifactId>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    ....
</dependencies>

 ...    
</project>

AppContext.xml:

<bean id="authService" scope="singleton" class="com.test.management.AuthServiceImpl" />

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" name="EntityManagerFactory">
        <property name="persistenceUnitName" value="default"></property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="${db.dialect}" />
            </bean>
        </property>     
    </bean>

    <!-- Values are defined in db.properties -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" name="TransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>

    <tx:annotation-driven />

    <bean id="userDAO" scope="singleton" class="com.test.database.dao.impl.UserDAOImpl">
    </bean>

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

</beans>

服务项目:

public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserDAO userDAO;

    @Override
    public void authorization() {
        userDAO.fooBar();

    }
}

当我尝试从EntityManager获取会话时,我捕获到以下异常:

java.lang.IllegalStateException: No transactional EntityManager available
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:223)
    at $Proxy121.unwrap(Unknown Source)
pw9qyyiw

pw9qyyiw1#

您必须使用@Transactional注解来注解方法:

@Transactional
public void fooBar() {
   // Exception from this line
   Session session = getEntityManager().unwrap(Session.class);
   ...
}

并且,如有必要,例如在使用普通Spring框架时,在Spring的xml配置文件中使用以下声明启用Spring @Transactional处理(其中txManager是管理器的ID):

<tx:annotation-driven transaction-manager="txManager" />
tjvv9vkg

tjvv9vkg2#

试试这个?

entityManager=entityManager.getEntityManagerFactory().createEntityManager();
Session session = (Session) entityManager.unwrap(Session.class);
bweufnob

bweufnob3#

所有这些都对我不起作用,我最终发现问题是我将方法设置为@Transactional,而不是我需要类设置为@Transactional

t5fffqht

t5fffqht4#

在我的情况下,这是另一个问题(对于那些谁有问题的@交易):

  • @Transactional* 需要一个动态的代理才能工作。它的代理需要精确地基于接口(JDK代理。在这种情况下CGLIB不工作)。因此,通过服务创建接口并实现它,@Transactional 注解将工作。
c3frrgcw

c3frrgcw5#

在我的例子中,当我定义自定义方法时,例如findStudentByFirstName,这个异常开始出现。这个问题通过在仓库类中添加@Transactional注解得到了解决。

package com.sample.application.studentmanagementapplication.dao;

import com.sample.application.studentmanagementapplication.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import javax.transaction.Transactional;
import java.util.List;

@Repository
@Transactional
public interface StudentRepository extends JpaRepository<Student, Long> {

    List<Student> findByFirstName(String name);

}

相关问题