Hibernate & Spring Roo: org.hibernate.PersistentObjectException: detached entity passed to persist

StackOverflow https://stackoverflow.com/questions/22802536

Frage

I'm using Spring Roo to generate an entity based on a table(created on the MS SQL Server). The following is my sql script:

CREATE TABLE [dbo].[JMSMessage](
     [MessageID] [nvarchar](100) NOT NULL,
     [Destination] [varchar](50) NOT 
     [Status] [varchar](15) NULL,
CONSTRAINT [PK_JMSMessage] PRIMARY KEY CLUSTERED 
(
    [MessageID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Java entity generated by Spring Roo is

@Entity
@Table(schema = "dbo",name = "JMSMessage")
@Configurable
public class Jmsmessage {

    @Column(name = "Destination", length = 50)
    @NotNull
    private String destination;

    @Column(name = "Status", length = 15)
    private String status;

    public String getDestination() {
        return destination;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "MessageID", length = 100)
    private String messageId;

    public String getMessageId() {
        return this.messageId;
    }

    public void setMessageId(String id) {
        this.messageId = id;
    }

    @PersistenceContext
    transient EntityManager entityManager;

    public static final EntityManager entityManager() {
        EntityManager em = new Jmsmessage().entityManager;
        if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

    public static Jmsmessage findJmsmessage(String messageId) {
        if (messageId == null || messageId.length() == 0) return null;
        return entityManager().find(Jmsmessage.class, messageId);
    }

    @Transactional
    public void persist() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.persist(this);
    }

    @Transactional
    public void remove() {
        if (this.entityManager == null) this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Jmsmessage attached = Jmsmessage.findJmsmessage(this.messageId);
            this.entityManager.remove(attached);
        }
    }

    @Transactional
    public void flush() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.flush();
    }

    @Transactional
    public void clear() {
        if (this.entityManager == null) this.entityManager = entityManager();
        this.entityManager.clear();
    }

    @Transactional
    public Jmsmessage merge() {
        if (this.entityManager == null) this.entityManager = entityManager();
        Jmsmessage merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }

    public String toString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

Then when i run the following code to create an entity instance and try to persistent it, the program throws an PersistentObjectException saying "detached entity passed to persist".

Jmsmessage message = new Jmsmessage();
message.setMessageId("m1");
message.setDestination("queue1");
message.setStatus("status1");
message.persist(); // If i use message.merge(), it will throws another Sql exception saying "Cannot insert the value NULL into column 'MessageID'"

How can i make the persistent work, any suggestions? Thanks in advance!

War es hilfreich?

Lösung

You should not set a value for messageId, because you have the strategy to @GeneratedValue(strategy = GenerationType.AUTO)

On another note, I notice that you have used the active record pattern that roo provides. I suggest that you change this to the DAO pattern since code like this in very uncommon in the Java/Spring/Hibernate world :)

Andere Tipps

You have ID generation strategy auto but you have assigned some id value in your entity. Meaning ORM engine will consider your fresh entity as detached entity since it got id and it will throw exception like trying to save detached entity.. if you try to merge the entity to overcome the problem , ORM engine will check the id you provided to the entity and it will not able to match any row against your entity since there is no such row with that primary key..
Bottom line of the error is, you are confusing the ORM engine with Id generation.

Hope This is helpful!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top