7

My problem is with detached objects...

I am currently using Spring with Hibernate.

I have a mapped object that has a primary key as a String (I know it sucks... but refactoring the code would take months), and I wish to persist it. (I have simplified the object with just two attributes)

@Id
private String id;

private String pattern;

So for example I want to add something like:

["id":"myFirstPattern","pattern":".*"]

Notice that my primary key is already set. The problem with that is that whenever I try to persist, Hibernate will try to link this object with any object within the context (because of the primary key) and will fail to do so, since there are none. Throwing a detached object error.

I've done some research and came to the conclusion that merge() would suffice my needs, since it persists and updates even if the object is not available. However I found this a rather dirty workaround and wanted to check if there are any other solutions to this problem.

Take into account that we have a Helper layer, so Services layer will not work directly with the HibernateDao layer. So I can "mask" this by adding 'persist' and 'update' methods that will invoke the same merge DAO method.

Thanks, Flavio.

flavio_yama
  • 313
  • 1
  • 4
  • 10

3 Answers3

1

Have you tried saveOrUpdate?

Session sess = factory.openSession();
Transaction tx;
try {
    tx = sess.beginTransaction();
    session.saveOrUpdate( yourObjectHere );

    tx.commit();
}
catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
}
finally {
    sess.close();
}
Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
  • I tried using SaveOrUpdate, but I believe my cached database messes up with JUnit, since I remove some data manually via sql queries. I keep getting StaleStateException errors when I try to persist the same object a second time after I removed it in the test before. It is unlikely that we will do any manual removes, but still that is why JUnits are there, to test everything. – flavio_yama Jul 29 '11 at 14:12
1

I tried using some different approach after I tried the idea Mauricio gave to me. Since SaveOrUpdate was using the cached entities to verify if it should update or save an object I thought about making a clear just before saving my object.

so, here is my piece of code:

try {
        getHibernateTemplate().clear();
        getHibernateTemplate().save(entity);
    } catch (DataAccessException e) {
        if (e.getCause() instanceof ConstraintViolationException)
            throw new HibernateDaoException("Entity could not be persisted. Constraint violation.");
        throw new HibernateDaoException(e);
    }

For now, it is working as expected, even though it seems that it will kill my cached database reason to exist... However this update feature will be used sparingly, as the main reason for the component is returning info, matching patterns and returning the best results.

Anyway I will return soon if I find any flaws.

Any comments, please feel free to post them :)

flavio_yama
  • 313
  • 1
  • 4
  • 10
0

I'm not certain, and I can't try it myself right now, but doesn't setting the @Id property to use the "assigned" generator do exactly that?

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • Couldnt find any specifically in the @Id, even though I found the others in GeneratedId, etc... Not sure how this will help me out. The GeneratedValue strategies are related to DB right ? I've worked with these before, but all of my previous experience were with normalized DBs... – flavio_yama Jul 29 '11 at 14:15