JPA DAO模式不提交

时间:2014-01-15 09:34:24

标签: java spring jpa spring-transactions

我在'独立Java SWING应用程序'中有下一个配置。 我有问题:我的服务运行没有错误,执行DAO删除方法,但不提交删除:

的persistence.xml

<persistence-unit name="springappPU" transaction-type="RESOURCE_LOCAL">
</persistence-unit>

弹簧-config.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:p="http://www.springframework.org/schema/p"
   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-      3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:annotation-config/>
<context:component-scan base-package="gestionclinicaecocitas">
</context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager" />

<!-- holding properties for database connectivity /-->
<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username"  value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>


<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
<property name="persistenceUnitName" value="springappPU"></property>
</bean>

<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}"
p:showSql="${jpa.showSql}"/>

在我的项目的main()中,初始化spring上下文,并获得一个'service'加载器类:

ClassPathXmlApplicationContext  ac= new ClassPathXmlApplicationContext("spring-config.xml");
ac.getBean(SpringServiceLoader.class);

我的SpringServiceLoader:

@Service
public class SpringServiceLoader{

    @Autowired
    private CalendarService calendarService;

我的serviceInterface方法标记为@Transactional

public interface CalendarioService {
@Transactional
    public void deleteDays();
}

服务调用dao delete方法的实现

@Service("calendarService")
public class CalendarioServiceImpl implements CalendarioService{


@Autowired
private DaysDaoImpl daysDao;

@Override
public void deleteDays{
        daysDao.deleteById(1);
}

}

最后是Dao结构:

@Repository
public class DaysDaoImpl extends GenericDaoImpl< Days > {

public DaysDaoImpl(){
  setClazz(Days.class );
}

GenericDao类:

import java.io.Serializable;
import java.util.List;

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

public abstract class GenericDaoImpl< T extends Serializable> {//implements GenericDao<T>{

@PersistenceContext
protected EntityManager em;
private Class< T > clazz;


public void setClazz( Class< T > clazzToSet ){
   this.clazz = clazzToSet;
}

(.....)   

public void deleteById( Long entityId ){
    this.em.remove(this.em.getReference(clazz, entityId));

}
}

我的实体类:

@Entity
@Table(name="calendar_days")
public class Days implements java.io.Serializable {

@EmbeddedId
private DaysId id;

(....)

我还尝试了HQL查询,而不是调用基本的CRUD方法,我收到了错误:

TransactionRequiredException:执行更新/删除查询

 Query query = this.em
            .createQuery("delete from Days d where d.id.date < :fecha");
    query.setParameter("fecha", fecha);
    query.executeUpdate();

如果我尝试让em事务手动进行开始/提交,则错误将更改为:

不允许在共享的EntityManager上创建事务

由于

3 个答案:

答案 0 :(得分:0)

使用

T entity = em.find(persistentClass, id);

获取实体。然后致电

em.remove(entity);

或者将这条记录缩短为一行。

更新(感谢@ M.Deinum)

答案 1 :(得分:0)

最后我找到了解决方案。 标记为@Transactional的CalendarService接口有效,问题是SpringServiceLoader和CalendarService都被定义为@Service。

我已将CalendarService重命名为@Component构造型,它被自动连接到标记为@Service构造型的SpringServiceLoader,现在事务处理工作正常。

感谢大家的支持! 我将看一下Spring Data

答案 2 :(得分:-1)

解决此问题的一种非常简单的方法是向main()方法添加@Transactional