JPA find()工作,坚持没有异常没有结果,删除显示查询和抛出删除分离的实例异常

时间:2015-03-06 20:13:22

标签: java spring hibernate jpa

我不知道应该添加什么才能让它有效。 这是我的实体类:

@Entity
public class Student {

@Id
@GeneratedValue
private int id;
private String name;
private int age;

//setters and getters
}

我的application-context.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: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/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config />
<context:component-scan base-package="orm" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="wisla666"/>
</bean>

<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="orm.entity" />
    <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="org.hibernate.dialect.MySQLDialect" />
        </bean>     
    </property> 
</bean>

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

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

这是我的Dao课程:

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import orm.entity.Student;

@Repository
public class StudentDaoImpl implements StudentDao {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Student loadStudent(int id) {
        return entityManager.find(Student.class, id);
    }

    @Override
    public void saveStudent(Student student) {
        entityManager.persist(student);
    }

    @Override
    public void deleteStudent(Student student) {
        entityManager.remove(entityManager.merge(student));
    }
}

首先我从DB加载Student对象并且它可以工作,然后我尝试从DB中删除此对象,但它不起作用。在删除期间,可以看到sql语法:

Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from Student student0_ where student0_.id=?

并抛出异常:

java.lang.IllegalArgumentException: Removing a detached instance orm.entity.Student#2

在持久化期间,Student对象没有任何反应。

问题是如何才能使其有效?

2 个答案:

答案 0 :(得分:1)

代码:

@Repository
public class StudentDaoImpl implements StudentDao {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    @Override
    public Student loadStudent(int id) {
        return entityManager.find(Student.class, id);
    }
}

主要方法:

public static void main(String[] args) {
     ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
     StudentServiceImpl ssi = context.getBean("studentServiceImpl", StudentServiceImpl.class);
}

异常:使用名称&#39; studentServiceImpl创建bean时出错&#39;:注入自动连接的依赖项失败

这是我的问题:如果@Transactional不能与@PersistenceContext使用相同的plce?为什么我不能分配这个bean?

答案 1 :(得分:0)

调用loadStudent(int id)后,返回的Student实体将被分离 - 意味着不再附加到休眠会话。

由于它不再处于会话状态,因此无法执行删除操作。要解决此问题,您可以在事务方法中包装您的调用,以便在一个事务中执行查找和删除操作。

假设您有StudentService,则可以使用

@Service
public StudentServiceImpl implements StudentService {

     @Autowired
     private StudentDao studentDao;

     @Transactional
     public void remove(int id) {
           Student student = studentDao.loadStudent(id);
           studentDao.remove(student);
     }

}