33

I have a table with a generated id, but in some cases I would like to set it on my own. Can I, somehow, force Hibernate to ignore the @GeneratedValue?

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
woezelmann
  • 1,355
  • 2
  • 19
  • 39

4 Answers4

8

It may be an overkill but have you thought about writing your own CustomIDGenerator which probably subclasses say the AutoGenerator of hibernate and exposes a couple of methods where you can set the id of the next class object to be generated so for example

class MyGenerator extends .... {

public void setIdForObject(Class clazz, Long id) {
    //once you use this API, the next time an object of 
    //type clazz is saved the id is used
}

public void setIdForObject(Class clazz, Long id, Matcher matcher) {
    //once you use this API, the next time an object of 
    //type clazz is saved and the matcher matches yes the id will be 
    //assigned. Your matcher can match properties like name, age etc
    //to say the matched object
}
}

This could get complicated but at the least is possible as per hibernate doco

Kannan Ekanath
  • 16,759
  • 22
  • 75
  • 101
  • On the hibernate.org forums, there is a user that wrote his Generator class for this exact scenario: https://forum.hibernate.org/viewtopic.php?p=2404032 – tmarthal Feb 16 '11 at 22:14
  • I stumpled upon this request looking for a solution to the exact same question (though I am using EclipseLink instead of hibernate). I started using a custom ID generator but (at least in my EclipseLink scenario) there is one problem: How do I know if the object that needs to be persisted already has an ID or not? I don't have the entity object in my custom ID generator at hand. So I can't determine if I need to generate a new ID - in case the object does not have one. Or if I just return the id the object already has (or maybe null or whatever is necessary). – Jens Jun 16 '11 at 08:03
  • Add-on to my comment before: In EclipseLink, when creating an own Sequence generator there is a method called `shouldAlwaysOverrideExistingValue` which can be overridden. This seems to be a possible solution. Although it feels a little uncomfortable to override things I do not completely oversee and also didn't find any documentation to other than this [bug](https://bugs.eclipse.org/bugs/show_bug.cgi?id=300556) entry. – Jens Jun 16 '11 at 08:48
8

create your own identifiergenerator/sequencegenerator

public class FilterIdentifierGenerator extends IdentityGenerator implements IdentifierGenerator{

@Override
public Serializable generate(SessionImplementor session, Object object)
        throws HibernateException {
    // TODO Auto-generated method stub
    Serializable id = session.getEntityPersister(null, object)
            .getClassMetadata().getIdentifier(object, session);
    return id != null ? id : super.generate(session, object);
}

}

modify your entity as:

@Id
@GeneratedValue(generator="myGenerator")
@GenericGenerator(name="myGenerator", strategy="package.FilterIdentifierGenerator")
@Column(unique=true, nullable=false)
private int id;
...

and while saving instead of using persist() use merge() or update()

rakesh
  • 4,368
  • 1
  • 19
  • 13
7

Although this question was asked quite a while ago, I found the perfect answer for it in this post by @lOranger, and wanted to share it.

This proposal checks if the object's current id is set to something other than null, and if so, it uses it, otherwise, it generates it using the default (or configured) generation strategy.

It's simple, straight forward, and addresses the issue brought up by @Jens, of one not being able to retrieve the object's current id.

I just implemented it (by extending the UUIDGenerator), and it works like a charm :-D

Community
  • 1
  • 1
ahpoblete
  • 441
  • 8
  • 17
2

For you use case, you can manually add this no user. One way to do it is to put the insert operation on a file named "./import.sql" (in your classpath). Hibernate will go execute these statements when the SessionFactory is started.

  • @Emmanuel Bernard He said: **but, in some cases,** i would like to set it on my own. If you define how Hibernate should save an Entity (through "/.import.sql" file), so its automatic generation of identifier will not work, do not ? – Arthur Ronald Feb 05 '10 at 03:44
  • No it's unrelated, import.sql is plain SQL so you can do what you want, including updating the sequence or table id if needed – Emmanuel Bernard Feb 19 '10 at 13:55