gpt4 book ai didi

java - Spring 管理的事务未启动

转载 作者:行者123 更新时间:2023-12-01 09:15:37 29 4
gpt4 key购买 nike

应由 Spring 管理的事务未启动。

我是 Spring 新手,所以很可能这是一个需要解决的简单问题,但我在互联网上找不到任何可以为我指明正确方向的东西。

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="123" />

<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>

<bean id="employeeDAO" class="com.lucas.jpalearning.EmployeeDAO" />
<!-- <property name="entityManagerFactory" ref="entityManagerFactory" /> -->

<bean id="employeeDAOFactoryInjector" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

<property name="targetObject" ref="employeeDAO" />
<property name="targetMethod" value="setEntityManagerFactory" />
<property name="arguments">
<list>
<ref bean="entityManagerFactory"/>
</list>
</property>

</bean>

<tx:advice id="txEmployeeDAO" transaction-manager="txManager">

<tx:attributes>

<tx:method name="persist" propagation="REQUIRED"/>

</tx:attributes>

</tx:advice>

<aop:config>
<aop:pointcut id="employeePersistOperation" expression="execution(* com.lucas.jpalearning.EmployeeDAO.*(..))"/>
<aop:advisor advice-ref="txEmployeeDAO" pointcut-ref="employeePersistOperation"/>
</aop:config>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/lucas"/>
<property name="username" value="lucas"/>
<property name="password" value="XXXXX"/>
</bean>



<context:component-scan base-package="com.lucas.jpalearning" />
<tx:annotation-driven transaction-manager="txManager"/>

<!-- similarly, don't forget the PlatformTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

</beans>

EmployeeDAO.java:

package com.lucas.jpalearning;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;


public class EmployeeDAO {

private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;

public EmployeeDAO() {

}

//setters for EntityManagerFactory - will be injected by Spring
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {

this.entityManagerFactory = entityManagerFactory;
this.setEntityManager(this.entityManagerFactory.createEntityManager());

}

private EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}

private void setEntityManager(EntityManager entityManager) {

this.entityManager = entityManager;

}

private EntityManager getEntityManager() {

return this.entityManager;

}

public void persist(Employee employee) {

this.getEntityManager().persist(employee);

this.getEntityManager().flush();


}

}

Main.java:

package com.lucas.jpalearning;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class App
{

@PersistenceContext
private static EntityManager em;

public static void main( String[] args )
{
System.out.println( "Hello World!" );

//EntityManagerFactory emf = Persistence
// .createEntityManagerFactory("123");
//em = emf.createEntityManager();

ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:META-INF/spring/applicationContext.xml");
EmployeeDAO employeeDAO = ctx.getBean("employeeDAO", EmployeeDAO.class);

employeeDAO.persist(new Employee(1, "Ravi", "Raj", "Textile"));

//createEmployee(1, "Ravi", "Raj", "Textile");
//createEmployee(2, "Amit", "Raj", "IT");
//createEmployee(3, "Nitish", "Kumar", "Marketing");
}


}

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.lucas</groupId>
<artifactId>jpalearning</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>jpalearning</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9-atlassian-1</version>
</dependency>

<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4-redhat-2</version>
</dependency>

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>


<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.0.Final</version>
</dependency>

<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1208-jdbc42-atlassian-hosted</version>
</dependency>

</dependencies>

<repositories>

<repository>
<id>jBoss-releases-repository</id>
<name>JBoss Releases Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases/</url>
</repository>

<repository>
<id>atlassian-3rd-party-repository</id>
<name>Atlassian 3rd-Party Repository</name>
<url>https://maven.atlassian.com/3rdparty/</url>
</repository>

<repository>
<id>redhat-ga-repository</id>
<name>Redhat GA Repository</name>
<url>https://maven.repository.redhat.com/ga/</url>
</repository>

</repositories>

</project>

持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_2_0.xsd"
version="2.0">

<persistence-unit name="123" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>

<mapping-file>META-INF/jpa/orm.xml</mapping-file>

<class>com.lucas.jpalearning.Employee</class>

<properties>

<!-- Java Database Connection Specific Properties -->

<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/lucas" />
<property name="javax.persistence.jdbc.username" value="lucas" />
<property name="javax.persistence.jdbc.password" value="XXXX" />

<!-- Hibernate Specific Properties -->
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />

</properties>
</persistence-unit>
</persistence>

控制台输出:

Hello World!
Nov 12, 2016 5:56:13 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@306a30c7: startup date [Sat Nov 12 05:56:13 BRST 2016]; root of context hierarchy
Nov 12, 2016 5:56:13 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from URL [file:/home/lucas/workspace/jpalearning/target/classes/META-INF/spring/applicationContext.xml]
Nov 12, 2016 5:56:13 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2ef5e5e3: defining beans [entityManagerFactory,employeeDAO,employeeDAOFactoryInjector,txEmployeeDAO,org.springframework.aop.config.internalAutoProxyCreator,employeePersistOperation,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,dataSource,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,txManager]; root of factory hierarchy
Nov 12, 2016 5:56:14 AM org.springframework.orm.jpa.LocalEntityManagerFactoryBean createNativeEntityManagerFactory
INFO: Building JPA EntityManagerFactory for persistence unit '123'
Nov 12, 2016 5:56:14 AM org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
Nov 12, 2016 5:56:14 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.2.0.Final}
Nov 12, 2016 5:56:14 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Nov 12, 2016 5:56:14 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Nov 12, 2016 5:56:14 AM org.hibernate.cfg.Configuration addResource
INFO: HHH000221: Reading mappings from resource: META-INF/jpa/orm.xml
Nov 12, 2016 5:56:14 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Nov 12, 2016 5:56:14 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20
Nov 12, 2016 5:56:14 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: true
Nov 12, 2016 5:56:14 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [org.postgresql.Driver] at URL [jdbc:postgresql://localhost:5432/lucas]
Nov 12, 2016 5:56:14 AM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {password=****, autocommit=true, release_mode=auto}
Nov 12, 2016 5:56:15 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
Nov 12, 2016 5:56:15 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
Nov 12, 2016 5:56:15 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
Nov 12, 2016 5:56:15 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000102: Fetching database metadata
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000396: Updating schema
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: public.employee
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [firstname, id, dept, lastname]
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: []
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [employee_pkey]
Nov 12, 2016 5:56:15 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
Hibernate:
select
nextval ('hibernate_sequence')
Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:993)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at com.sun.proxy.$Proxy16.flush(Unknown Source)
at com.lucas.jpalearning.EmployeeDAO.persist(EmployeeDAO.java:51)
at com.lucas.jpalearning.EmployeeDAO$$FastClassByCGLIB$$26523180.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
at com.lucas.jpalearning.EmployeeDAO$$EnhancerByCGLIB$$93660a78.persist(<generated>)
at com.lucas.jpalearning.App.main(App.java:29)

编辑:

在 Spring 中使用 log4j 后,我注意到 Spring 正在启动事务,但显然也没有将其回滚。

2016-11-15 02:14:09 DEBUG DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'employeeDAO'
2016-11-15 02:14:09 DEBUG DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'txManager'
2016-11-15 02:14:09 DEBUG JpaTransactionManager:367 - Creating new transaction with name [com.lucas.jpalearning.EmployeeDAO.persist]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2016-11-15 02:14:09 DEBUG JpaTransactionManager:371 - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@611f8234] for JPA transaction
2016-11-15 02:14:09 DEBUG AbstractTransactionImpl:158 - begin
2016-11-15 02:14:09 DEBUG LogicalConnectionImpl:212 - Obtaining JDBC connection
2016-11-15 02:14:09 DEBUG LogicalConnectionImpl:218 - Obtained JDBC connection
2016-11-15 02:14:09 DEBUG JdbcTransaction:69 - initial autocommit status: true
2016-11-15 02:14:09 DEBUG JdbcTransaction:71 - disabling autocommit
2016-11-15 02:14:09 DEBUG SQL:104 -
select
nextval ('hibernate_sequence')
Hibernate:
select
nextval ('hibernate_sequence')
2016-11-15 02:14:09 DEBUG LogicalConnectionImpl:212 - Obtaining JDBC connection
2016-11-15 02:14:09 DEBUG DriverManagerConnectionProviderImpl:196 - Opening new JDBC connection
2016-11-15 02:14:09 DEBUG DriverManagerConnectionProviderImpl:219 - Created connection to: jdbc:postgresql://localhost:5432/lucas, Isolation Level: 2
2016-11-15 02:14:09 DEBUG LogicalConnectionImpl:218 - Obtained JDBC connection
2016-11-15 02:14:09 DEBUG SequenceGenerator:127 - Sequence identifier generated: BasicHolder[java.lang.Integer[60]]
2016-11-15 02:14:09 DEBUG AbstractSaveEventListener:130 - Generated identifier: 600, using strategy: org.hibernate.id.SequenceHiLoGenerator
2016-11-15 02:14:10 DEBUG JpaTransactionManager:851 - Initiating transaction rollback
2016-11-15 02:14:10 DEBUG JpaTransactionManager:538 - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@611f8234]
2016-11-15 02:14:10 DEBUG AbstractTransactionImpl:203 - rolling back
2016-11-15 02:14:10 DEBUG JdbcTransaction:164 - rolled JDBC Connection
2016-11-15 02:14:10 DEBUG JdbcTransaction:126 - re-enabling autocommit
2016-11-15 02:14:10 DEBUG JpaTransactionManager:600 - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@611f8234] after transaction
2016-11-15 02:14:10 DEBUG EntityManagerFactoryUtils:435 - Closing JPA EntityManager
2016-11-15 02:14:10 DEBUG LogicalConnectionImpl:232 - Releasing JDBC connection
2016-11-15 02:14:10 DEBUG LogicalConnectionImpl:250 - Released JDBC connection
Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress

最佳答案

需要进行一些更改。

applicationContext.xml:使用LocalContainerEntityManagerFactoryBean。我们想要使用数据源(连接池源)的原因。删除employeeDAOFactoryInjector,因为我们可以使用@PersistenceContext注释 Autowiring EntityManager,而且您不应该手动创建实体管理器。还将事务管理器类型更改为 PlatformTransactionManager(原因:底部链接)。

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="123" />
<!-- <property name="packagesToScan" value="com.lucas.jpalearning"/> -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- Remove this injector -->
<!-- <bean id="employeeDAOFactoryInjector" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> -->

<!-- Also change transaction manager type -->
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

EmployeeDAO 类:

public class EmployeeDAO{

@PersistenceContext
private EntityManager entityManager;

//remove setEntityManagerFactory()

}

现在应该可以适应这些更改。

由于您在少数地方使用了注释并启用了事务注释驱动,所以让我们尝试一下注释方式。

删除 xml 中的 tx-adviceaop 标记。

将 spring 注解 @Transactional 放在 EmployeeDAO.persist() 方法上。

@Transactional
public void persist(Employee employee) {
this.getEntityManager().persist(employee);
this.getEntityManager().flush();
}

注释中的默认事务传播类型是必需,如果没有,事务管理器将创建。

What transaction manager to use? (JPA, Spring)

关于java - Spring 管理的事务未启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40560916/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com