@Id @GeneratedValue but set own ID value

2019-01-06 22:05发布

问题:

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?

回答1:

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



回答2:

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



回答3:

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()



回答4:

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.