-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 10:04 am 
Newbie

Joined: Sat Jan 06, 2007 3:46 pm
Posts: 15
Hibernate 3.3.1.GA, SpringFramework 3.1.1.RELEASE, annotations, MySQL 5.5.x

I've got a small web service I'm putting together that successfully creates objects that end up in the DB, but it can't update existing objects. I'm not really sure where to look. The code looks basically like this:

Code:
SaveCard card = mSaveCardDAO.findForPlayerAndGame(p, g);
if (card == null)
{
    card = mSaveCardDAO.createSaveCard(p, g, inData);
}
else
{
    sGCLogger.info("----------------------------------- Updating save card date");
    card.setLastModified(new Date());
    card.setData(inData);
    mSaveCardDAO.makePersistent(card);
    sGCLogger.info("----------------------------------- Made persistent");
}


Hibernate logs this. What does "ignoring persistent instance" mean?

Code:
06:54:14.089 INFO  web.ServiceController (ServiceController.java:357) ----------------------------------- Updating save card date
06:54:14.089 TRACE impl.SessionImpl (SessionImpl.java:1316) setting flush mode to: AUTO
06:54:14.089 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:82) begin
06:54:14.089 DEBUG jdbc.ConnectionManager (ConnectionManager.java:444) opening JDBC connection
06:54:14.090 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:87) current autocommit status: true
06:54:14.090 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:90) disabling autocommit
06:54:14.090 TRACE jdbc.JDBCContext (JDBCContext.java:237) after transaction begin
06:54:14.090 TRACE def.AbstractSaveEventListener (AbstractSaveEventListener.java:511) persistent instance of: com.lz.gamecenter.model.SaveCard
06:54:14.090 TRACE def.DefaultSaveOrUpdateEventListener (DefaultSaveOrUpdateEventListener.java:122) ignoring persistent instance
06:54:14.091 TRACE def.DefaultSaveOrUpdateEventListener (DefaultSaveOrUpdateEventListener.java:159) object already associated with session: [com.lz.gamecenter.model.SaveCard#1]
06:54:14.091 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:134) commit
06:54:14.091 TRACE impl.SessionImpl (SessionImpl.java:364) automatically flushing session
06:54:14.091 TRACE jdbc.JDBCContext (JDBCContext.java:228) before transaction completion
06:54:14.091 TRACE impl.SessionImpl (SessionImpl.java:420) before transaction completion
06:54:14.091 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:227) re-enabling autocommit
06:54:14.092 DEBUG transaction.JDBCTransaction (JDBCTransaction.java:147) committed JDBC Connection
06:54:14.092 TRACE jdbc.JDBCContext (JDBCContext.java:242) after transaction completion
06:54:14.092 DEBUG jdbc.ConnectionManager (ConnectionManager.java:325) transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
06:54:14.092 TRACE impl.SessionImpl (SessionImpl.java:449) after transaction completion
06:54:14.092 TRACE impl.SessionImpl (SessionImpl.java:1316) setting flush mode to: MANUAL
06:54:14.092 DEBUG impl.SessionImpl (SessionImpl.java:401) disconnecting session
06:54:14.093 TRACE jdbc.ConnectionManager (ConnectionManager.java:403) performing cleanup
06:54:14.093 DEBUG jdbc.ConnectionManager (ConnectionManager.java:464) releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
06:54:14.093 TRACE jdbc.JDBCContext (JDBCContext.java:242) after transaction completion
06:54:14.093 DEBUG jdbc.ConnectionManager (ConnectionManager.java:325) transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
06:54:14.093 TRACE impl.SessionImpl (SessionImpl.java:449) after transaction completion
06:54:14.093 INFO  web.ServiceController (ServiceController.java:361) ----------------------------------- Made persistent


The code is wrapped in a org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.

Any ideas or suggestions? Thank you.


Top
 Profile  
 
 Post subject: Re: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 8:37 pm 
Newbie

Joined: Sat Jan 06, 2007 3:46 pm
Posts: 15
Here's the SaveCard model object:

Code:
package com.lz.gamecenter.model;

//
//  Java Imports
//

import java.util.Date;

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 javax.persistence.Temporal;
import javax.persistence.TemporalType;


//
//  Third-party Imports
//

import org.apache.log4j.Logger;

import org.hibernate.annotations.Proxy;


//
//  Project Imports
//





@Entity
@Table
@Proxy(lazy = true)
public
class
SaveCard implements java.io.Serializable
{
    public  Long                getId()                                 { return mId; }
    public  void                setId(Long inVal)                       { mId = inVal; }
   
    public  Long                getPlayerId()                           { return mPlayerId; }
    public  void                setPlayerId(Long inVal)                 { mPlayerId = inVal; }
   
    public  Player              getPlayer()                             { return mPlayer; }
    public  void                setPlayer(Player inVal)                 { mPlayer = inVal; }
   
    public  Long                getGameId()                             { return mGameId; }
    public  void                setGameId(Long inVal)                   { mGameId = inVal; }
   
    public  Game                getGame()                               { return mGame; }
    public  void                setGame(Game inVal)                     { mGame = inVal; }
   
    public  Date                getLastModified()                       { return mLastModified; }
    public  void                setLastModified(Date inVal)             { mLastModified = inVal; }
   
    public  byte[]              getData()                               { return mData; }
    public  void                setData(byte[] inVal)                   { mData = inVal; }
   
    public
    String
    toString()
    {
        StringBuffer sb = new StringBuffer();
        sb.append("SaveCard ").append(getId());
        sb.append(", Player ").append(getPlayerId());
        sb.append(", Game ").append(getGameId());
        return sb.toString();
    }
   
   
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected   Long                mId;
   
    @ManyToOne
    @JoinColumn(name = "mPlayerId", nullable = false)
    protected   Player              mPlayer;
    @Column(insertable = false, updatable = false)
    protected   Long                mPlayerId;
   
    @ManyToOne
    @JoinColumn(name = "mGameId", nullable = false)
    private Game                mGame;
    @Column(insertable = false, updatable = false) 
    private Long                mGameId;
   
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false, updatable = false)
    protected   Date                mLastModified;
   
    protected   byte[]              mData;
   
    private static  Logger          sLogger                 =   Logger.getLogger(SaveCard.class);
}


Top
 Profile  
 
 Post subject: Re: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 8:38 pm 
Newbie

Joined: Fri Oct 19, 2012 8:28 pm
Posts: 2
The problem might be that the existing object might be cached in the Hibernate Session, and the entity in the update method conflicts with what Hibernate thinks is in its cache. If this is the problem, then the way around this is to merge the entity rather than call update or save. That way, Hibernate merges the supplied entity with what it may have in its cache, avoiding the problem of conflict with cached entity. flush then creates/updates the merged entity.

T ret = jpaDALLimpl.entityManager.merge(entity);
jpaDALLimpl.entityManager.flush();


Top
 Profile  
 
 Post subject: Re: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 8:51 pm 
Newbie

Joined: Sat Jan 06, 2007 3:46 pm
Posts: 15
Thanks Shanker. Unfortunately, that results in this:

Code:
17:50:27.298 ERROR hibernate.AssertionFailure (AssertionFailure.java:47) an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: Merged entity does not have status set to MANAGED; EntityEntry[com.lz.gamecenter.model.SaveCard#1](READ_ONLY) status=READ_ONLY


I'm pretty sure saveOrUpdate() should work, that there's just something wrong in my config somewhere.


Top
 Profile  
 
 Post subject: Re: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 9:09 pm 
Newbie

Joined: Fri Oct 19, 2012 8:28 pm
Posts: 2
If the object is being serialized and sent over the wire, you may need to detach it before sending it, and atttach it again before merging (in that case, merge may not even be needed, the attach will do the needful). Unfortunately I do not have the syntax for the attach and detach calls handy.


Top
 Profile  
 
 Post subject: Re: Can create new objects but not update existing ones
PostPosted: Fri Oct 19, 2012 9:21 pm 
Newbie

Joined: Sat Jan 06, 2007 3:46 pm
Posts: 15
I've found the answer. Your suggestion of trying merge() resulted in logging that indicated something was READ_ONLY, which was indeed the case. There were two issues.

The first was that the entity was fetched via a setReadOnly(true) org.hibernate.Query:

Code:
@Transactional(readOnly = true)
public
SaveCard
findForPlayerAndGame(Player inPlayer, Game inGame)
{
    Session session = getSession();
   
    Query q = session
                .createQuery("from SaveCard t where t.mPlayer = :p and t.mGame = :g")
                .setParameter("p", inPlayer)
                .setParameter("g", inGame)
                .setReadOnly(true)      //  This prevents updating the returned entity
                .setMaxResults(1);
    SaveCard result = (SaveCard) q.uniqueResult();
    return result;
}


Once I resolved that (by removing the setReadOnly(true) call), one of the two columns I was trying to update was still not updating. A look at the configuration of that column revealed updatable=false:

Code:
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false, updatable = false)
protected   Date                mLastModified;


Fixing this (by changing updatable = true) resolved all the issues. I do still have to call Session.saveOrUpdate(card) on the resulting entity to get the changes to persist, which I thought wasn't strictly necessary, but I'm okay with that.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.