简体   繁体   English

保存工作,但在休眠4.1.1中仍然无法工作

[英]save working but persist not working in hibernate 4.1.1

I am trying to save data usign hsqldb and I am using hibernate 4.1.4.Final. 我试图保存数据usged hsqldb我正在使用hibernate 4.1.4.Final。 My problem is I want to save data using persist but when I tried to do it's showing following error: 我的问题是我想使用持久保存数据,但是当我尝试这样做时,它显示以下错误:

org.hibernate.PersistentObjectException: detached entity passed to persist: main.java.entity.Advocate
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:835)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:828)
    at org.hibernate.engine.spi.CascadingAction$7.cascade(CascadingAction.java:315)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:844)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:819)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:823)
    at main.java.service.LegalService.registerCase(LegalService.java:46)
    at main.java.tester.Tester.registerCase(Tester.java:52)
    at main.java.tester.Tester.main(Tester.java:28)

But when I use save method it worked.So I want to know how persist and save makes difference? 但是当我使用保存方法时它起作用了,所以我想知道持久性和保存有何不同? and my entity classes are serialized.How to solve this persist error. 和我的实体类已序列化。如何解决此持久性错误。

Here is my class 这是我的课

package main.java.service;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

import main.java.businessTier.CaseTO;
import main.java.entity.Advocate;
import main.java.entity.Case;

public class LegalService {

     Configuration configuration = new Configuration().configure();

     ServiceRegistry  serviceRegistry = new ServiceRegistryBuilder().applySettings(
               configuration.getProperties()). buildServiceRegistry();
    SessionFactory   sessionFactory = configuration.buildSessionFactory(serviceRegistry);







    public int registerCase(CaseTO caseTO) {
        try
        {
             Session session;
           session=sessionFactory.openSession();
           session.beginTransaction();

        Case c = new Case();
        Advocate a = new Advocate();
         a.setAdvocateId(caseTO.getAdvocateId());
        c.setAdvocate(a);
        c.setClientAge(caseTO.getClientAge());
        c.setClientName(caseTO.getClientName());
        c.setDate(caseTO.getDate());
        c.setDescription(caseTO.getDescription());

        session.persist(c);
        session.getTransaction().commit();
        return c.getCaseNo();
        }
        catch(Exception e){
            e.printStackTrace();
            return 0;
        }



    }

}

Here are my entity class Advocate.java 这是我的实体类Advocate.java

package main.java.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name="Db_Advocate")
@DynamicInsert(value=true)
@DynamicUpdate(value=true)
public class Advocate {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="advocateId")
    private Integer advocateId;

    @Column(name="name")
    private String name;
    @Column(name="age")
    private Integer age;
    @Column(name="category")
    private String category;
    @Column(name="court")
    private String court;
    @Column(name="city")
    private String city;
    public Integer getAdvocateId() {
        return advocateId;
    }
    public void setAdvocateId(Integer advocateId) {
        this.advocateId = advocateId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getCategory() {
        return category;
    }
    public void setCategory(String category) {
        this.category = category;
    }
    public String getCourt() {
        return court;
    }
    public void setCourt(String court) {
        this.court = court;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }



}

Case.java Case.java

package main.java.entity;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name="DB_CASE")
@DynamicInsert(value=true)
@DynamicUpdate(value=true)
public class Case {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer caseNo;
    @JoinColumn(name="advocateId")
    @ManyToOne(cascade=CascadeType.ALL)
    private Advocate advocate;
    private String clientName;
    private Integer clientAge;
    private String description;
    private Date date;


    public Integer getCaseNo() {
        return caseNo;
    }

    @Column(name="caseNo")
    public void setCaseNo(Integer caseNo) {
        this.caseNo = caseNo;
    }
    public Advocate getAdvocate() {
        return advocate;
    }


    public void setAdvocate(Advocate advocateId) {
        this.advocate = advocateId;
    }
    public String getClientName() {
        return clientName;
    }
    public void setClientName(String clientName) {
        this.clientName = clientName;
    }
    public Integer getClientAge() {
        return clientAge;
    }
    public void setClientAge(Integer clientAge) {
        this.clientAge = clientAge;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Date getDate() {
        return date;
    }

    @Column(name="data",nullable=true)
    public void setDate(Date date) {
        this.date = date;
    }



}

Please Add below code at id 请在id处添加以下代码

@Id @GeneratedValue(strategy = GenerationType.AUTO) @Id @GeneratedValue(strategy = GenerationType.AUTO)

Then persist will work 然后坚持会起作用

First you need to understand behaviour of persist(). 首先,您需要了解persist()的行为。 Below are the links that will help you understand the behaviour Whats the difference between persist() and save() in Hibernate? 以下是可以帮助您了解行为的链接: Hibernate中的persist()和save()之间有什么区别? http://javarevisited.blogspot.in/2012/09/difference-hibernate-save-vs-persist-and-saveOrUpdate.html http://javarevisited.blogspot.in/2012/09/difference-hibernate-save-vs-persist-and-saveOrUpdate.html

Now in order to solve this problem in your code .. use merge() instead of persist(). 现在为了在你的代码中解决这个问题..使用merge()而不是persist()。

Why persist() gave the exception 为什么persist()给出了异常

persist() does not work for detached objects .You need to know how hibernate determines whether an object is detached or not. persist()对分离的对象不起作用。您需要知道休眠是如何确定对象是否分离的。

UPDATE UPDATE

Why the identifier generation strategy auto solved your problem 为什么标识符生成策略会自动解决您的问题

As i mentioned above that you need to understand the rules by which hibernate identifies whether an object is detached or transient. 正如我上面提到的,您需要了解休眠标识对象是分离的还是瞬态的规则。 Below are the rule 以下是规则

  1. If the the entity has a null value for identifier or the version attribute is null it is considered as transient other wise detached. 如果实体的标识符值为null或version属性为null,则将其视为瞬态(否则)分离。

  2. If you use auto-generated identifiers, and the identifier is not null, then Hibernate considers it as a detached entity. 如果使用自动生成的标识符,并且标识符不为null,则Hibernate会将其视为独立实体。

  3. If you are using assigned identifier strategy then hibernate will issue a fetch to determine whether the identifier exists in db based on that your entity will be either transient or detached. 如果您使用的是已分配的标识符策略,那么hibernate将发出一个提取,以确定该标识符是否存在于db中,因为您的实体将是瞬态或分离的。

Now that being said .. we analyse your code. 现在说..我们分析你的代码。

In your code you have Advocate entity whose identifier strategy is IDENTITY.In the below code 在您的代码中,您有Advocate实体,其标识符策略为IDENTITY。在下面的代码中

  Case c = new Case();
    Advocate a = new Advocate();
     a.setAdvocateId(caseTO.getAdvocateId());

You are setting the identifier property of Advocate instance manually.At the time of flush when transaction commits ,hibernate will see that the identifier generation strategy is IDENTITY and the identifier value is set in the advocate instance hence it will conclude that the entity instance is detached (this is from the rule 1 described above).And hence the persist() method gave exception for the advocate instance as it is deemed to be detached from hibernate. 您正在手动设置Advocate实例的标识符属性。在事务提交时刷新的时间,hibernate将看到标识符生成策略为IDENTITY,并且在提供者实例中设置标识符值,因此它将断定实体实例已分离(这来自上面描述的规则1)。因此,persist()方法为propate实例提供了异常,因为它被认为与hibernate分离。

From rule 2 we can say that your code will not work just by changing the generation strategy to auto.You might have done some other changes. 从规则2我们可以说,只需将生成策略更改为auto,您的代码就无法工作。您可能已经做了一些其他更改。

I have tried your code on my system it is giving the same exception even if i change the generation strategy to auto which is in consistent with the rules 我已经在我的系统上尝试过你的代码,即使我将生成策略更改为auto,这也符合规则

You might be doing something different in your code .. please check and update. 您可能在代码中执行了不同的操作..请检查并更新。

Please also post the identifier that you are setting in the advocate and the actual identifier generated for that advocate in database with auto generation strategy, that might be helpful 还请发布您在倡导者中设置的标识符以及使用自动生成策略在数据库中为该拥护者生成的实际标识符,这可能会有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM