How to prevent Hibernate from using 0 as ID? - java

I am using
#TableGenerator(name="tab",initialValue=2,allocationSize=50)
on Entities and define the ID with
#Id
#GeneratedValue(generator="tab",strategy=GenerationType.TABLE)
private int id;
yet Hibernate still uses 0 as an ID.
I cannot use #GenericGenerator because the annotations do not come with Hibernate4 that ships with Jboss AS7.
Is there a simple solution or do I have to write a custom Generator?

Hibernate is creating ids with id 0 because you have a primitive type. Try using Integer id instead of int id. Remember primitives can't hold a null value.
If you want to generate the custom id generator, you can use a SEQUENCE in DB to generate the id if the object.
<id ....>
<generator class="sequence">
<param name="sequence">YOUR_SEQUENCE _NAME</param>
</generator>
</id>
Read the API about generator classes here.

Related

Is Generator class need for ID tag in Hibernate?

I am new to Hibernate and question is "Is Generator class need for ID tag in Hibernate?"
In my table have trigger mentioned below and my table is existing table and having records.Just I did code change from Native SQL to Hibernate session. in this case "Is Generator class need for ID tag in Hibernate? or not" . Here my exception is record need to insert with next sequence value.
TRIGGER TRG_BI_APPLICATION_DATA_LOCK
BEFORE INSERT
ON APPLICATION_DATA_LOCK REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
exception_no_null_pk EXCEPTION;
BEGIN
IF :new.APP_DATA_LOCK_ID is null
THEN
SELECT SEQ_APPLICATION_DATA_LOCK_PK.nextval
INTO :new.APP_DATA_LOCK_ID
FROM dual;
END IF;
END;
Assuming before insert call trigger will create next ID value and insert will happen. So, in hbm file, we need generator class or if we need means which generator have to use?
Please help me in this regard...
Thanks...
I'm going to infer what you are asking from your question title and the answer to that is no, you don't need a #GeneratedValue annotation for your ID to work, only if you want to specify that a) your ID is going to be a value not generated by Hibernate, and b) if you want to specify how your ID is going to be generated.
I think what you need to do is this:
#Entity
#Table
public class Foo{
#Id
#GeneratedValue(generator = "applicationLockSequence")
#SequenceGenerator(name = "applicationLockSequence" sequenceName = "SEQ_APPLICATION_DATA_LOCK_PK")
private int id;
....
}
This basically specifies that there is a sequence on the database with that name, and that Hibernate should use that sequence to assign your object an ID when it gets saved. There is no need to do this at a database level with a trigger, although that is also a valid method. If you want to do it with a trigger, just leave out #GeneratedValue and #SequenceGenerator.
Hope that answers your question.
TL;DR OP is using a .hbm file for hibernate mappings.
As given here: How To Use Sequence In Hibernate As A Property In XML Mapping
<id name="id" column="item_id>
<generator class="sequence">
<param name="sequence">SEQ_APPLICATION_DATA_LOCK_PK</param>
</generator>
</id>
should be all you need to do this.

Hibernate unsaved-value annotation

I would like to force Hibernate (4.2) checking object persistence by the field VERSION instead of the field ID. The xml below should work:
<id name="id" column="ID">
<generator class="assigned" />
</id>
<version name="version" column="VERSION" unsaved-value="null" />
But I want to use annotations. Is this java code enough?
#Id
public String getId() {
return this.id;
}
#Version
public Integer getVersion() {
return this.version;
}
How to specify the unsaved-value tag? I don't find any annotation for this.
I've read somewhere, that Hibernate is smart enough to guess that an object is persistent or not, but it was not too convincing.
And what if I want to use -1 instead of null? There must be a way to achieve this, isn't it?
<version name="version" column="VERSION" unsaved-value="negative" />
Thanks for your help.
Edited. Hibernate 3.6 ref guide says:
"The unsaved-value attribute is almost never needed in Hibernate3 and indeed has no corresponding element in annotations."
and
"The assigned generator makes Hibernate use unsaved-value="undefined". This forces Hibernate to go to the database to determine if an instance is transient or detached, unless there is a version or timestamp property, or you define Interceptor.isUnsaved()."
I belive #Version will be sufficient for me.

Hibernate GUID local generator

I use hibernate to generate ids for my MySQL data-tables:
<class name="XXXX" table="XXXX">
<id name="Id" column="Id" type="string">
<generator class="guid"/>
</id>
....
</class>
it works fine.
however, when i profiling the sql queried, there are 2 sqls for 1 insert:
1).select uuid() and then 2).insert ....
I have 3 questions:
why not hibernate generates the "GUID"s locally?
how much is the overhead for "select uuid()" than "UUID.randomUUID()" for one insert?
can i config a "local" generator in hibernate?
AFAIK the GUID generator is deprecated and you should use the new(er) UUIDGenerator instead. See http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e5294.
But to answer your questions
That is how the GUID generator functions it calls the database and the result is passed into the id field of the object
No idea, measure, however I guess the impact is negligible as the only thing you do additionally is return a simply value
Yes but why as it is already supported by Hibernate (see the documentation)

Java - Openjpa: how to specify sequence generator starting from hibernate hbm

I've to switch persistence of a project using HIBERNATE to OPENJPA and I started from entities and hbm files which define type of columns, etc.
I've an Id on hibernate generated in this way:
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="sequence">
<param name="sequence">seq_illness</param>
</generator>
</id>
how can I "translate" it ointo Jpa annotation to my entity class, in particular how can I represent sequence generator?
I'm new to this feature and I don't understand well usage of
#GeneratedValue(strategy = GenerationType.SEQUENCE)
how can I reproduce sequence parameter and define the correct sequence generator?
In JPA, the mapping for this column would look like:
#Id
#SequenceGenerator(name="ID_GEN" sequenceName="NAME_OF_SEQ_IN_DB")
#GeneratedValue(generator="ID_GEN")
private Integer id;
See the following documentation for further information:
#SequenceGenerator
#GeneratedValue

how to disable generator when db trigger creates id

Currently when I try to insert new records I am getting an error:
[ERROR] 05/12/11_09:44:20.54 [org.hibernate.event.def.AbstractFlushingEventListener] - Could not synchronize database state with session
Db2 triggers to generate the ID need to remain in place to support legacy applications. How can I configure the hbm.xml to not generate the ID?
I'm not sure what version of Hibernate you are using, but Hibernate currently supports getting an ID that is generated from trigger via a special generator called select.
In short, you can add this generator to your ID column, and then reference a natural key you can use to retrieve the trigger generated ID as follows:
<id name="id" type="long" column="person_id">
<generator class="select">
<param name="key">socialSecurityNumber</param>
</generator>
</id>
If your mapping already has a natural-key entry defined, then you shouldn't even need to specify the key param to the generator.
One problem with this particular generator is that you can only use one entity property as the selection key for it. If you need to select via a composite key, then you'll have to create your own generator for this purpose.
You could extend org.hibernate.id.SelectGenerator or one of it's parents, and then implement the select via multiple columns that way. Then you simply replace the class attribute of the above generator entry with the fully qualified class name of your new generator.

Categories