When does the JPA set a @GeneratedValue @Id
calling .persist() will not automatically set the id value. Your JPA provider will ensure that it is set before the entity is finally written to db. So you are right to assume that the id will be assigned when the transaction is committed. But this is not the only possible case. When you call .flush() the very same will happen.
Thomas
Update: Pay attention to Geek's comment, please. -> If GenerationType.Identity is used, the id will not be set by the provider before the entity is written to db. In this case id generation happens during the insert process on db level. Anyway, the JPA provider will ensure that the entity is updated afterwards and the generated id will be available in the @Id annotated property.
JPA @GeneratedValue and @Id
Well I don't think that this would work. JPA automatically generates your id value and is responsible for the @GeneratedValue
. Ask yourself 'what happens if there is already an existing entity with the id 100. And I create manually a new entity with tne id 100'. Intuitively I would say that JPA (or the implementation) throws an expection.
While writing the above answer I got the idea of writing your own generator (not tried at all, just coded down here at stackoverflow.
You can pass your own implementation of a generator to the @GeneratedValue
annotation
@Id
@GeneratedValue(startegy = GenerationType.IDENTITY, generator="generatedIdOrCustomId")
@GenericGenerator(name="generatedIdOrCustomId", strategy="GeneratedIdOrCustomId")
private Long id;
...
And the custom implementation should look like this:
public class GeneratedIdOrCustomId extends IdentityGenerator {
@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
if (((YourEntity) obj).getId() == null) {
// the id is null, let JPA create an id.
return super.generate(session, obj);
} else {
// the id is set and should not be generated by JPA.
return ((YourEntity) obj).getId();
}
}
The generate method is just a quick and dirty implementation. You'll have to check for example also if the obj == null
and throw a (Hibernate)Exception
in this case.
Hibernate JPA Generate id
puid
has default value 0, when an object is just created.- Hibernate thinks that you set
puid
value manually, Hibernate doesn't change it.
Just changelong
toLong
to havenull
initial value.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long puid;
what is the use of annotations @Id and @GeneratedValue(strategy = GenerationType.IDENTITY)? Why the generationtype is identity?
First of all, using annotations as our configure method is just a convenient method instead of coping the endless XML configuration file.
The @Id
annotation is inherited from javax.persistence.Id
, indicating the member field below is the primary key of current entity. Hence your Hibernate and spring framework as well as you can do some reflect
works based on this annotation. for details please check javadoc for Id
The @GeneratedValue
annotation is to configure the way of increment of the specified column(field). For example when using Mysql
, you may specify auto_increment
in the definition of table to make it self-incremental, and then use
@GeneratedValue(strategy = GenerationType.IDENTITY)
in the Java code to denote that you also acknowledged to use this database server side strategy. Also, you may change the value in this annotation to fit different requirements.
1. Define Sequence in database
For instance, Oracle has to use sequence
as increment method, say we create a sequence in Oracle:
create sequence oracle_seq;
2. Refer the database sequence
Now that we have the sequence in database, but we need to establish the relation between Java and DB, by using @SequenceGenerator
:
@SequenceGenerator(name="seq",sequenceName="oracle_seq")
sequenceName
is the real name of a sequence in Oracle, name
is what you want to call it in Java. You need to specify sequenceName
if it is different from name
, otherwise just use name
. I usually ignore sequenceName
to save my time.
3. Use sequence in Java
Finally, it is time to make use this sequence in Java. Just add @GeneratedValue
:
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
The generator
field refers to which sequence generator you want to use. Notice it is not the real sequence name in DB, but the name you specified in name
field of SequenceGenerator
.
4. Complete
So the complete version should be like this:
public class MyTable
{
@Id
@SequenceGenerator(name="seq",sequenceName="oracle_seq")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
private Integer pid;
}
Now start using these annotations to make your JavaWeb development easier.
@Id @GeneratedValue but set own ID value
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
How to set initial value for @Id @GeneratedValue in Spring JPA for MySQL?
You could try and use the @TableGenerator (JPA has a @TableGenerator annotation in which you can set an initial value). The initialValue can be used to seed the values
Example here : http://www.java2s.com/Code/Java/JPA/SetInitialValueOfTableGenerator.htm
Related Topics
Javafx Launch Another Application
Java Swing; Two Classes, Where to Put If Statements and New Actionlisteners
Get Yesterday's Date Using Date
Parsing JSON with Gson, Object Sometimes Contains List Sometimes Contains Object
How Many Threads Are Spawned in Parallelstream in Java 8
Java 8 Lambdas Group List into Map
What Is the Point of the Class Option[T]
How to Capture a Jframe's Close Button Click Event
How to Enumerate Ip Addresses of All Enabled Nic Cards from Java
Spring @Autowired and @Qualifier
Access Restriction: Is Not Accessible Due to Restriction on Required Library ..\Jre\Lib\Rt.Jar
Why Only 1 Public Class in Java File
Sending the Same But Modifed Object Over Objectoutputstream
Java Jdbc MySQL Exception: "Operation Not Allowed After Resultset Closed"