从DB中删除对象,JPA

时间:2016-04-21 08:06:22

标签: java spring jpa

这是我的DAO方法:

public void deleteById(int id){
    TypedQuery<Animal> query = entityManager.createQuery("Select e from Animal e where e.id="+id, Animal.class);
    Animal entity = query.getSingleResult();
    System.out.println(entityManager.contains(entity));
    System.out.println(entity.hashCode());
    entity = entityManager.merge(entity);
    System.out.println("after merge");
    System.out.println(entity.hashCode());
    System.out.println(entityManager.contains(entity));
    entityManager.remove(entity);
}

这是我的控制者:

@RequestMapping("{animal}/{name}/{id}/delete")
public String dropAnimal(@PathVariable("id") int id){

    animalDAO.deleteById(id);
    return "glowny";
}

当我尝试删除对象时,我删除了一个分离的实例时出错。

我在合并之前和之后做了sysout,两者都是假的,但我不知道为什么。为什么我的物体仍然分离?

  

java.lang.IllegalArgumentException:删除分离的实例kaczynski.impl.Cat#1       在org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:69)       在org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:106)       在org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73)       在org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:920)       在org.hibernate.internal.SessionImpl.delete(SessionImpl.java:896)       在org.hibernate.jpa.spi.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:1214)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)       at java.lang.reflect.Method.invoke(Unknown Source)       在org.springframework.orm.jpa.ExtendedEntityManagerCreator $ ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)       在com.sun.proxy。$ Proxy22.remove(未知来源)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)       at java.lang.reflect.Method.invoke(Unknown Source)       在org.springframework.orm.jpa.SharedEntityManagerCreator $ SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)       在com.sun.proxy。$ Proxy22.remove(未知来源)       at kaczynski.DBaccess.AnimalDAO.deleteById(AnimalDAO.java:88)       at kaczynski.DBaccess.AnimalDAO $$ FastClassBySpringCGLIB $$ 5f2786e9.invoke()       在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)       在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)       at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)       在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)       at kaczynski.DBaccess.AnimalDAO $$ EnhancerBySpringCGLIB $$ 53a0549d.deleteById()       在kaczynski.web.AnimalsController.dropAnimal(AnimalsController.java:48)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)       at java.lang.reflect.Method.invoke(Unknown Source)       在org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)       在org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)       在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)       在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)       在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)       在org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)       在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)       在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)       在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)       在org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)       在javax.servlet.http.HttpServlet.service(HttpServlet.java:622)       在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)       在javax.servlet.http.HttpServlet.service(HttpServlet.java:729)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)       在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)       在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)       在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)       在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)       在org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)       在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)       在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)       在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)       at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:672)       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1500)       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1456)       at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)       at org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)       在java.lang.Thread.run(未知来源)

在stackTrace之前我有这条消息:

  

kwi 21,2016 10:47:45 AM org.apache.catalina.core.StandardWrapperValve invoke       严重:servlet [mvc-dispatcher]的Servlet.service()在路径[/zapisywacz.baza]的上下文中引发异常[请求处理失败;嵌套异常是org.springframework.dao.InvalidDataAccessApiUsageException:删除分离的实例kaczynski.impl.Cat#1;嵌套异常是java.lang.IllegalArgumentException:删除带有根本原因的分离实例kaczynski.impl.Cat#1]

这是hascodes的输出:

false
1870474474
after merge
445252736
false

的persistence.xml

<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="myDatabase" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <properties>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.user" value="tutorial" />
        <property name="javax.persistence.jdbc.password" value="password" />
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mojaBaza" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect " />
        <property name="hibernate.hbm2ddl.auto" value="update" />
    </properties>
</persistence-unit>

动物实体

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;

    private String name;

    private int age;
    @Column(name="date_of_birth")
    private String dateOfBirth;

    private double weight;

    public Animal(String name, int age, String dateOfBirth, double weight) {
        this.name = name;
        this.age = age;
        this.dateOfBirth = dateOfBirth;
        this.weight = weight;
    }

    public Animal() {}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(String dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return " id= " + id + " name=" + name + ", age=" + age
                + ", dateOfBirth=" + dateOfBirth + ", weight=" + weight;
    }

    public String tease() {
        return "";
    }

    public String giveVoice() {
        return "";
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

2 个答案:

答案 0 :(得分:1)

我找到了解决方案,

弹簧配置中的

缺失,并且因为注释@Transactional,弹簧不可见。

答案 1 :(得分:0)

合并后,该对象与会话分离并删除它,您必须再次找到它。

TypedQuery<Animal> query = entityManager.createQuery("Select e from Animal e where e.id="+id, Animal.class);
Animal entity = query.getSingleResult();
entityManager.remove(entity);