ORACLE AUTO INCREMENT jpa - jpa

i have prob with mapping sequence auto increment
#GeneratedValue(strategy=GenerationType.SEQUENCE)
i'm using on sql developer it work but when i try on netbeans i get the message
Caused by: java.lang.NullPointerException

Create a sequence named SOME_SEQ in your db for this particular table. And use the annotations above your id field. allocationSize=1 means increment the value by 1. And some_seq_gen_name is for unique labeling.
#Id
#Column(name = "id")
#GeneratedValue(generator="some_seq_gen_name")
#SequenceGenerator(name="some_seq_gen_name", sequenceName="SOME_SEQ", allocationSize=1)
private Long id;
UPDATE: Based on your comment, for commit try this one:
EntityTransaction et = em.getTransaction();
et.begin();
// write persist code here
et.commit();

Related

Alternative initial value for entity in JPA

I have the following entity and their mapping
#Entity
#Table(name = "test")
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator", initialValue = 20000)
I want id value begins in 20000 but it doesn't work in postgresql. When the application starts I receive this exception
Caused by: org.hibernate.HibernateException: Multiple references to
database sequence [sequence_generator] were encountered attempting to
set conflicting values for 'initial value'. Fou nd [20000] and [1]
Do I need a extra configuration to it works?
PS: It is a new database without any previous configuration
You could try #TableGenerator annotation. Initial values can be set and seed other values.
You can find example and documentation here:
Set Initial Value Of Table Generator

How to make primary key value in each table should start from numeric One (1) - PostgreSQL , Spring data jpa

In my current project we are using PostgreSQL as DB and Spring data JPA for persistence. In all entity classes we are using GenerationType.SEQUENCE for generation of primary key value. It's working fine. But, the value for the primary key in each table not starting from 1 . The value is always next increment value of the maximum number of other table's primary key.
How can we change this ? . How to make primary key value of each table should start from 1.
You need to configure a sequence per table. This answer explains how to do that.
I'm just quoting it here:
Contents of my package-info.java:
#GenericGenerator(
name = "optimized-sequence",
strategy = "enhanced-sequence",
parameters = {
#Parameter(name="prefer_sequence_per_entity", value="true"),
#Parameter(name="optimizer", value="hilo"),
#Parameter(name="increment_size", value="50")})
package org.example.model;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
On the usage side you just need
#Id #GeneratedValue(generator="optimized-sequence")
public long id;
Below code on ID worked for me.
#Id
#SequenceGenerator(name = "MY_ENTITY_SEQ", sequenceName = "MY_ENTITY_SEQ", allocationSize=1)
#GeneratedValue(strategy = GenerationType.AUTO, generator = "MY_ENTITY_SEQ" )
#Column(updatable = false, nullable = false)
private Integer id;
Please let me know if i face any issues with this approach in future.

Postgres insert record with Sequence generates error - org.postgresql.util.PSQLException: ERROR: relation "dual" does not exist

I am new to Postgres database.
I have a Java Entity class with the below column for ID:
#Entity
#Table(name = "THE_RULES")
public class TheRulesEntity {
/** The id. */
#Column(name = "TEST_NO", precision = 8)
#SequenceGenerator(name = "test_no_seq", sequenceName = "TEST_NO_SEQ")
#GeneratedValue(generator = "test_no_seq", strategy = GenerationType.AUTO)
#Id
private Long id;
/** The test val. */
#Column(name = "TEST_VAL", nullable = false, length = 3)
private String testVal;
Code:
rulesRepository.saveAndFlush(theRulesEntity)
Table:
CREATE TABLE THE_RULES
(
TEST_NO INT NOT NULL,
TEST_VAL VARCHAR(3) NOT NULL
)
CREATE SEQUENCE "TEST_NO_SEQ" START WITH 1000 INCREMENT BY 1;
When I try to insert a new record into the postgres database from my application (the ID value is null in Java code during Debug mode), then I get the below error:
Caused by: org.postgresql.util.PSQLException: ERROR: relation "dual" does not exist
But If I insert the record manually into database table and then update the record from my application, then the record is updated successfully (Probably because the application uses the same ID value so no need to refer to the Sequence TEST_NO_SEQ value anymore)
Looks like the database is not able to access the sequence from dual table.
Could anyone help me how to fix this?
Thanks.
Thanks to Joop and a_horse_with_no_name, the issue is resolved
I have used Oracle driver which is wrong. I have updated my code to use Postgres driver
I created the Sequence again in the database with same name but without the Quotes
I used all capital-case letters in my Java entity class to refer to the sequence correctly

JPA and Postgres sequence pre-allocation size setup incorrectly

I am not able to perist any Entity because of a problem with sequence. I use Glssfish 4, Postgres 9.3 + JPA + EJB3 and Netbeans 8.
Below the excpeption:
Finest: persist() operation called on: MyUser{id=null, email=a#e.it, password=test, firstname=test, lastname=test, company=Test}.
Finest: Execute query ValueReadQuery(sql="select nextval('mom_seq_id')")
Finest: Connection acquired from connection pool [read].
Finest: reconnecting to external connection pool
Fine: select nextval(mom_seq_id)
Finest: Connection released to connection pool [read].
Warning: Local Exception Stack:
Exception [EclipseLink-7027] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The sequence named [mom_seq_id] is setup incorrectly. Its increment does not match its pre-allocation size.
at org.eclipse.persistence.exceptions.ValidationException.sequenceSetupIncorrectly(ValidationException.java:1604)
at org.eclipse.persistence.sequencing.StandardSequence.createVector(StandardSequence.java:96)
...
The sequence on Postgres:
CREATE SEQUENCE my_seq_id
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 27
CACHE 1;
ALTER TABLE my_seq_id
OWNER TO postgres;
COMMENT ON SEQUENCE my_seq_id
IS 'Sequence for autoincrement id on MyClass';
And an extract of my Entity:
#Entity
#Table(name = "myuser")
#XmlRootElement
public class MyUser implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name="MYSEQ",
sequenceName="my_seq_id")
#GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="MYSEQ")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
Can anyone explain what is wrong?
Thanks
I resolved my issue but I don't know why! I saw that the default value of allocationSize() is 50:
package javax.persistence;
#Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
#Retention(value = RetentionPolicy.RUNTIME)
public #interface SequenceGenerator {
public String name();
public String sequenceName() default "";
public String catalog() default "";
public String schema() default "";
public int initialValue() default 1;
public int allocationSize() default 50;
}
And I have updated my Postgres sequence increment_by value from 1 to 50 and now it works!
For reasons beyond my understanding, the JPA spec picked 50 as the default increment for a sequence generator.
PostgreSQL defaults to 1.
If the two don't match, things get ugly, because JPA thinks it can use values that someone else also thinks they have assigned. At least EclipseLink detects this; Hibernate just goes on merrily trying to re-use already assigned keys.
If your sequence is:
CREATE SEQUENCE my_seq_id
INCREMENT 1
then your mapping must reflect that:
#SequenceGenerator(name="MYSEQ",
sequenceName="my_seq_id", allocationSize=1)
I strongly suggest being explicit about the increment, even if you leave it at the default of 50 and alter the PostgreSQL sequence instead. It'll save your and others' sanity when debugging later.
Changing the value of INCREMENT from 1 to 50 into my Postgres sequence resolved the issue. As suggested by #unwichtich it is a good idea to specify allocationSize=50 attribute through the #SequenceGenerator annotation.

JPA: Usage of #GeneratedValue on non-id column

I am attempting to persist an entity with an attribute that I want to be populated from a DB sequence. I'm using Oracle, have created the sequence, verified the sequence works via sql, and yet my attribute isn't getting populated. Here's what I have:
#GeneratedValue(generator = "RFQ_LINE_IDS_SEQUENCE", strategy=GenerationType.SEQUENCE)
#SequenceGenerator(name="RFQ_LINE_IDS_SEQUENCE", sequenceName="RFQ_LINE_IDS_SEQUENCE", allocationSize=1000000000)
#Column(name = "external_line_item_id")
private String externalLineItemId;
All the examples I'm seen online show this annotation being used with #Id, but I have another attribute that I'm using for my id.
I've also tried the following to no avail:
#GeneratedValue(generator = "RFQ_LINE_IDS_SEQUENCE", strategy=GenerationType.SEQUENCE)
#GenericGenerator(name = "RFQ_LINE_IDS_SEQUENCE", strategy = "sequence",
parameters = {#Parameter(name = "sequence", value = "RFQ_LINE_IDS_SEQUENCE")})
#Column(name = "external_line_item_id")
private String externalLineItemId;
JPA only mandates support for #GeneratedValue on #Id fields. Some JPA implementations (such as DataNucleus JPA) support it but not all do.
I have created a proposal for JPA to support #GeneratedValue for non-id attributes. Please vote here for this to be included in 2.2
https://java.net/jira/browse/JPA_SPEC-113