Spy*_*Bot 8 java spring repository transactional
我正在尝试使用Spring,JPA和嵌入式H2数据库进行简单的应用程序.最近我遇到了声明性交易这个奇怪的问题.如果我使用@Repository注释自动装配我的DAO,它们就不会提交.更具体地说,我在flush上获得异常:
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
Run Code Online (Sandbox Code Playgroud)
这是我的设置:
<persistence-unit name="schedulePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/scheduleDB" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.H2Platform" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
Run Code Online (Sandbox Code Playgroud)
@Entity
@Table(name = "Professors")
public class Professor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
public Professor() { }
public Professor(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
@Repository
public class JpaDao {
@PersistenceContext
private EntityManager em;
@Transactional
public void addProfessor(Professor professor) {
em.persist(professor);
em.flush();
}
}
Run Code Online (Sandbox Code Playgroud)
<beans>
<context:component-scan base-package="com.spybot.schedule.dao" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="schedulePU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
Run Code Online (Sandbox Code Playgroud)
@Controller
public class HomeController {
@Inject
JpaDao dao;
@RequestMapping("/add")
public @ResponseBody String add(String name) {
Professor p = new Professor(name);
dao.addProfessor(p);
return ":)";
}
}
Run Code Online (Sandbox Code Playgroud)
现在是有趣的部分.如果我从DAO中删除@Repository注释并在database.xml中显式指定它,一切正常.
将另一个<tx:annotation-driven />置于spring servlet配置中可以解决问题,但为什么呢?
可能是因为component-scan在你spring-servlet.xml的扫描中还包括你的DAO类,因此在它的应用程序上下文(而不是"数据库")中为它们创建实例...所以当你的web从web控制器访问这些DAO时,它正在访问它们的非事务版本(除非您添加该tx:annotation-driven标记).
因此,添加该标记实际上是一个糟糕的解决方案,因为它仍然在错误的应用程序上下文中创建DAO实例:更好地base-package为Web层组件创建创建更具体的配置.
我有同样的问题,因为我认为<context:include-filter>在我的spring-servlet.xml照顾只扫描@Controller类...但没有:-(
| 归档时间: |
|
| 查看次数: |
10107 次 |
| 最近记录: |