I have a class that is an entity of a table from a PostgreSQL database:
#Entity
#Table(name = "users")
public class User {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Getter private Long id;
...
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL NOT NULL UNIQUE,
...
When the application starts, this table fills with some test data (from .sql file trough "INSERT INTO..."). However, when a new instance is created in the database trough Hibernate, the ID always starts with one, forcing me to create it multiple times until generated ID reaches the required value.
I need the ID counter to start with a number, that is one more than the ID of the previous record in the table. Ideally not requiring me to manually specify the ID value.
You can define your entity like this:
#Entity
#Table(name = "users")
#SequenceGenerator(name = "sequence", sequenceName = "mySequence")
public class User {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
#Getter private Long id;
And then in your .sql file write insert queries like this:
INSERT INTO users values (select nextval('mySequence'), ...
select nextval('mySequence')
will give you next available value from sequence table
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_custom_sequence")
#SequenceGenerator(name="your_custom_sequence", sequenceName = "MY_CUSTOM_SEQ", allocationSize=1)
and you can define your sequence in sql like CREATE SEQUENCE MY_CUSTOM_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 20 NOMAXVALUE;
Related
Using hibernate 5.4, postgres 10 with IntelIiJ Ultimate, impossible to get auto-incremented primary key
with this following code, the sequence "warehouses_id_seq" is created but the primary key is not incremented
#Entity
#Table(name = "warehouses")
#SequenceGenerator(name = "SEQUENCE_WAREHOUSE", sequenceName = "warehouses_id_seq", allocationSize = 1)
public class Warehouse implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_WAREHOUSE")
#Column(name = "id")
private Integer id;
I added below line to fix the problem:
#ColumnDefault("nextval('public.warehouses_id_seq')");
But I'm quite desapointed, I expected Hibernate to do it automaticaly with the SequenceGenerator...
#Entity
public class FooSequence {
#Id
#SequenceGenerator(name="foo_seq_id", sequenceName="seq_id_K", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="foo_seq_id")
#Column(name = "E_I")
private Long value;
}
#Entity
#Table(name="Emp")
public class Whatever {
#Id
#SequenceGenerator(name="seq_id", sequenceName="seq_id", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_id")
private Long id;
#OneToOne
private FooSequnce fooSeq;
}
I have a table with mutliple Sequence where one column is a primary key and the other is an normal column and both not nullable field.
When I try to save the MyEntity table it is generating Sequence id for the FooSequence entity but it was trying to insert a row into the database for FooSequence and getting error.Do we need to have a seperate table in this case.
Can't we achieve without the other new table for FooSequence.
Sorce Link
I've got a #MappedSuperclass which is my base-class for all my entities (#Entity, direct or indirect through multiple sub-classing).
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#XmlAttribute(required = true)
private Long primaryKey;
The Id is generated like shown above.
My problem is that the #Id-counter is the same for each #Entity. In fact thats not a big problem because it would take a while to reach the Long.MAX_VALUE. But reaching that maximum value is a lot easier because there is only one counter for all entities. How can I use a different #Id-counter without having to add the above code to all #Entity-classes?
(If it matters for your answer: I'm using a H2-Database.)
If your database and tables support AUTO_INCREMENT change the annotation to this #Id #GeneratedValue(strategy=GenerationType.IDENTITY). Then the id will be generated during commit.
There is another way via TABLE or SEQUENCE strategy, but it needs to be explicitly defined per Entity which is problem for abstract BaseEntity. Just hava a look:
#Entity
#TableGenerator(name="tab", initialValue=0, allocationSize=50)
public class EntityWithTableId {
#GeneratedValue(strategy=GenerationType.TABLE, generator="tab")
#Id long id;
}
EDIT:
Well, so it is possible!
MappedSuperclass - Change SequenceGenerator in Subclass
#Id
#Column(name = "ID", unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.TABLE, generator = "SEQ_AAAAAAAAAAA")
#TableGenerator(
name = "SEQ_AAAAAAAAAAA",
table = "SEQ_ENTITY" /*<<<==YOUR TABLE NAME FOR SAVE NEXT VALUES HERE*/,
pkColumnName = "ENTITY",
initialValue = 1,
valueColumnName = "NEXT_ID",
pkColumnValue = "packageee.PACK.PAK.YOURCLASSNAME",
allocationSize = 1)
private Long id;
I have a Table (for a long time ago), call it TABLE_A, and I have an entity class for this Table:
#Entity
#Table(name = "TABLE_A")
public class TableA implements Serializable {
#Id
#Basic(optional = false)
#Column(name = "ID")
//what else should I write here, to get the value from the existing sequence (seq_table_a_id) from database?
private Long id;
#Basic(optional = false)
#Column(name = "VALID_TO_DT")
private String name;
getters/setters...
}
I had created a sequence for this table in ORACLE a long time ago, and I want to give values for the new item's ID from this sequence. How should I write this code in java entity with annotations? If you could write an example for my code, that would be helpful!
And should I write anything else maybe in the persistance.xml?
The name of the existing sequence is: seq_table_a_id
You should check the annotation #GeneratedValue and #SequenceGenerator
#Id
#GeneratedValue(generator="seqGen")
#SequenceGenerator(name="seqGen",sequenceName="seq_table_a_id", allocationSize=1)
private Long id;
Check this link
I'm usign #GeneratedValue(strategy = GenerationType.AUTO) to generate the ID on my entity.
I don't now how it works, but on my child table, generates ID values, that follow the parent sequence.
//parent table
#Entity
#Table (name = "parent")
public class Parent {
#Id
#GeneratedValue (strategy = GenerationType.AUTO)
#Column (name = "id")
private long id;
#OneToMany (cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
#JoinColumn (name = "parentId")
#ForeignKey (name = "FKparent")
private List<child> child;
}
//child table
#Entity
#Table (name = "child")
public class Child {
#Id
#GeneratedValue (strategy = GenerationType.AUTO)
#Column (name = "id")
private long id;
}
The inserted ID values on parent, updates the sequence.
The inserted ID values on child, updates the sequence.
On the next insert of parent, the sequence... uses values updated by child insertions...
This Annotations, aren't creating two sequences, only one. Is this correct/expected?
I inserted my entities with my DAO service only using entityManager.persist(parent);
These Annotations are no creating two sequences, only one. Is this correct/expected?
That's the expected behavior. When using #GeneratedValue(strategy = GenerationType.AUTO), the JPA provider will pick an appropriate strategy for the particular database. In the case of Oracle, this will be SEQUENCE and, since you did not specify anything, Hibernate will use a single global sequence called hibernate_sequence.
Is this correct? Well, I don't know, it depends on your needs. Just in case, the default maximum value for an Oracle sequence is 1E+27, or 1,000,000,000,000,000,000,000,000,000. That's enough for many.
Now, it is possible to use GenerationType.AUTO and still control the name of the sequence when the database uses sequences:
#Id
#GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
#SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private Long id;
Yes this is correct and expected.
You can create individual sequences for each table, but IMHO that is just extra code with no actual benefit.
#Entity
#Table(name = "table_seq")
#SequenceGenerator(name= "NAME_SEQUENCE", sequenceName = "SEQ_ID", initialValue=1, allocationSize = 1)
public class SeqEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="NAME_SEQUENCE")
private Long id;
}