ERROR: relation "hibernate_sequence" does not exist - postgresql

I do not want to use autoincrement id. I have this table in PostgreSQL:
CREATE TABLE public.project
(
id character varying(255) COLLATE pg_catalog."default" NOT NULL,
name character varying(255) COLLATE pg_catalog."default" NOT NULL,
number bigint NOT NULL,
state character varying(255) COLLATE pg_catalog."default",
CONSTRAINT project_pkey PRIMARY KEY (id)
)
And I have this model:
#Entity
#Table(name = "project")
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Project {
#Id
#Column(name = "id")
private String id;
#Column(name = "name")
private String name;
#Column(name = "number")
private BigInteger number;
#Column(name = "state")
private String state;
I want to use simple ID I do not want to use autoincrement and hibernate_sequence, and do not understand where I wrong.
And I have error:
ERROR 11088 --- [ restartedMain] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist

In our entity you should use #GeneratedValue(strategy = GenerationType.IDENTITY) on your id especially if your table will autoincrement id.

In my case I could solve the problem by upgrading the postgres driver to a more recent version which seems to work with different (older) postgres versions as well. (updated version in build.gradle):
implementation 'org.postgresql:postgresql:42.2.18'

You need to set spring.jpa.properties.hibernate.id.new_generator_mappings=false in your application.properties file.

Run:
CREATE SEQUENCE hibernate_sequence START 1;

Related

Use postgres table sequence instead of sharing hibernate_sequence

When I do anything with a table, it always show the error:
Hibernate: select nextval ('hibernate_sequence')
2019-07-20 16:15:44.877 WARN 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2019-07-20 16:15:44.877 ERROR 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
I DON'T want to use hibernate_sequence to share id sequence between tables, but want to define id seq for each table and use them respectively.
I use Spring Boot 2.1.6.RELEASE, Spring Data JPA (Hibernate 5.3.10.Final), and Postgres 11.2, and define the id field with BigSerial type and hope to use the id sequence of each table in respective entity class.
The demo repo is here: https://github.com/Redogame/share_hibernate_sequence
Create user table (use identity as table name because user is a Postgres reserved keyword).
By defining id with bigserial type, Postgres will create a identity_id_seq automatically, and I verified that identity_id_seq has been created successfully.
create table identity
(
id bigserial not null
constraint identity_pkey
primary key,
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null
constraint identity_identity_id_fk
references identity,
last_modified_date timestamp not null,
last_modified_by_id bigint not null
constraint identity_identity_id_fk_2
references identity,
version bigint not null
);
Specify a sequence generator to use this id sequence:
#Table(name = "identity")
public class UserEntity extends Auditable<Long> {
#Id
#SequenceGenerator(name="identity_id_seq", sequenceName = "identity_id_seq", initialValue=1, allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="identity_id_seq")
private Long id;
But it doesn't work. I also tried to config spring.jpa.hibernate.use-new-id-generator-mappings and spring.jpa.properties.hibernate.id.new_generator_mappings, but still not work.
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
properties:
hibernate:
id:
new_generator_mappings: false
I expect not to use hibernate_sequence, that is: don't execute select nextval ('hibernate_sequence') before/after any SQL statement.
Try the below steps
CREATE SEQUENCE IF NOT EXISTS manual_seq;
Change create table script
create table identity
(
id integer NOT NULL DEFAULT nextval('manual_seq'::regclass),
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null,
last_modified_date timestamp not null,
last_modified_by_id bigint not null,
version bigint not null,
CONSTRAINT manual_seq_pkey PRIMARY KEY (id)
);
I removed the foreign key constraint for testing purposes.
Update the entity mapping
#Entity
#Table(name = "identity")
#JsonIgnoreProperties(ignoreUnknown = true)
public class UserEntity extends Auditable<Long> {
#Id
#SequenceGenerator(name="manual-seq", sequenceName = "manual_seq",allocationSize = 1)
#GeneratedValue(generator="manual-seq")
private Long id;
#Basic
#Column(name = "name", nullable = false)
private String name;
#MappedSuperclass
#JsonIgnoreProperties({"new", "createdDate", "createdById", "lastModifiedDate", "lastModifiedById", "version"})
abstract class Auditable<PK extends Serializable>{
#NotAudited
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
#NotAudited
#CreatedBy
private Long createdById;
#LastModifiedDate
#Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
#LastModifiedBy
private Long lastModifiedById;
#NotAudited
#Version
private Long version;
Revert the spring.jpa.hibernate.use-new-id-generator-mappings
The issue was extending AbstractPersistable because of which database sequence was not getting used. Also, note I have removed the audit for testing purposes.
The same problem was happening to me. I explicitly set spring.jpa.properties.hibernate.id.new_generator_mappings=false but select nextval ('hibernate_sequence') was still run by Hibernate.
I found that when we use the #GeneratedValue annotation without setting a strategy, it defaults to AUTO, which means, Hibernate will try to generate the ID value using hibernate_sequence and then it wil fail because it doesn't exist in the database.
So, I made #GeneratedValue (strategy = GenerationType.IDENTITY) and tried again. In this case, the ID value was generated by my identity column in the database (the primary key that is automatically incremented) and not by hibernate_sequence.
create table users (id serial not null, name varchar(250), primary key (id));

Error in Sequence lookup in Hibernate for Postgresql

I am having problem in inserting data into Postgresql through Hibernate when Primary column has auto-increment.
I have gone through multiple post in this forum also, but can't find a solution that works for me.
My Table and Sequence are defined in "apiprofile" schema. When I run the code, it is unable to find the Sequence name.
Even if I mention it with the schema.sequence, still it doesn't work.
Any help is appreciated.
Below are the code snippet and exception I am facing.
Sequence & Table:
CREATE SEQUENCE apiprofile.login_session_id_seq;
CREATE TABLE apiprofile.login_session (
id bigint NOT NULL DEFAULT nextval('apiprofile.login_session_id_seq'),
username varchar(255) NOT NULL,
token varchar(500) NOT NULL,
active_ind boolean NOT NULL,
login_time timestamp NOT NULL,
PRIMARY KEY (id)
);
Bean file
public class LoginSession {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "session_generator")
#SequenceGenerator(name="session_generator", sequenceName = "apiprofile.login_session_id_seq", schema = "apiprofile", allocationSize=1)
#Column(name="id", updatable = false, nullable = false)
private Integer id;
Insert operation
LoginSession session = new LoginSession();
session.setUsername(userName);
session.setToken(token);
session.setActive(true);
session.setLoginTime(new Timestamp(System.currentTimeMillis()));
getSession().saveOrUpdate(session);
Exception
Hibernate:
select
next_val as id_val
from
login_session_id_seq for update
could not read a hi value
org.postgresql.util.PSQLException: ERROR: relation "login_session_id_seq" does not exist
Position: 32
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103) ~[postgresql-9.1-901-1.jdbc4.jar:?]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836) ~[postgresql-9.1-901-1.jdbc4.jar:?]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) ~[postgresql-9.1-901-1.jdbc4.jar:?]

Eclipselink JPA gets error when inserting into Derby table with generated primary key

EclipseLink seems to be incorrectly passing a null primary key value to Derby when persisting into a table with generated primary key. Derby returns error of Attempt to modify an identity column in this case. Derby needs a SQL statement that excludes the id value. My question is how do I coerce EclipseLink to send the right SQL? Details follow...
I am using Eclipselink to map to a Derby database (v10.8.1.2) under the latest Netbeans 7.3beta2.
The database table primary key is auto generated:
CREATE TABLE STUDENT_BATCH (
ID bigint PRIMARY KEY
GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
FILENAME varchar(200) NOT NULL,
SCHOOLBOARD varchar(100) NOT NULL,
CREATE_TS timestamp NOT NULL,
CONTACT_INFO varchar(200),
NOTES varchar(2000),
BOARD_NAME varchar(100)
)
;
The corresponding jpa class specifies that the id is generated using strategy of identity:
#Entity
#Table(name = "STUDENT_BATCH")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "StudentBatch.findAll", query = "SELECT s FROM StudentBatch s")})
public class StudentBatch implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private Long id;
#Basic(optional = false)
#Column(name = "FILENAME")
private String filename;
#Basic(optional = false)
#Column(name = "SCHOOLBOARD")
private String schoolboard;
#Basic(optional = false)
#Column(name = "CREATE_TS")
#Temporal(TemporalType.TIMESTAMP)
private Date createTs;
#Column(name = "CONTACT_INFO")
private String contactInfo;
#Column(name = "NOTES")
private String notes;
#Column(name = "BOARD_NAME")
private String boardName;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "studentBatchId")
private Collection<StudentRecord> studentRecordCollection;
methods etc follow...
When I go to persist the class, I do not specify an id so that Derby will provide the id.
StudentBatch sb = new StudentBatch();
sb.setBoardName(meta.get("BOARD NAME"));
sb.setContactInfo(meta.get("CONTACT INFO"));
sb.setCreateTs(new Date());
sb.setFilename(event.getFile().getFileName());
sb.setNotes(meta.get("NOTES"));
sb.setSchoolboard(meta.get("SCHOOL BOARD"));
_logger.debug("persisting batch");
em.persist(sb);
_logger.debug("flushing");
em.flush();
_logger.debug("flushed");
Eclipselink, however, passes the id to derby as null and Derby gives error Attempt to modify an identity column:
INFO: DEBUG 11710 27 Nov 2012 18:17:10,558 [http-thread-pool-8080(4)] (FileUploadController.java:75) - persisting batch
INFO: DEBUG 11713 27 Nov 2012 18:17:10,561 [http-thread-pool-8080(4)] (FileUploadController.java:77) - flushing
WARNING: Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: Attempt to modify an identity column 'ID'.
Error Code: -1
Call: INSERT INTO STUDENT_BATCH (ID, BOARD_NAME, CONTACT_INFO, CREATE_TS, FILENAME, NOTES, SCHOOLBOARD) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [7 parameters bound]
Query: InsertObjectQuery(ca.ontario.mhltc.studentupload.model.StudentBatch[ id=null ])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
This makes some sense to me since if I try to execute an insert on sql command line with the id field specified I get an error too.
INSERT INTO STUDENT_BATCH (id, BOARD_NAME, CONTACT_INFO, CREATE_TS, FILENAME, NOTES, SCHOOLBOARD)
VALUES (null, 'abc', 'def', current_timestamp, 'aaa', 'aabb', '1234');
gives me this:
Error code -1, SQL state 42Z23: Attempt to modify an identity column 'ID'.
Line 1, column 1
Execution finished after 0 s, 1 error(s) occurred.
however, this insert statement is successful:
INSERT INTO STUDENT_BATCH (BOARD_NAME, CONTACT_INFO, CREATE_TS, FILENAME, NOTES, SCHOOLBOARD)
VALUES ('abc', 'def', current_timestamp, 'aaa', 'aabb', '1234');
returns
Executed successfully in 0.002 s, 1 rows affected.
Line 1, column 1
Execution finished after 0.002 s, 0 error(s) occurred.
Seems to me that Eclipselink should know about how Derby handles identity columns and should not pass the id column at all on the insert statement. Is there a workaround for this or I should I just dump Derby and use some other database?
EclipseLink does not include the Id in the INSERT for Derby IDENTITY, so you have something odd going on.
Did you previously use another generator strategy and not recompile/deploy your code correctly?
Also try setting your platform using the"eclipselink.target-database"="Derby" in your persistence.xml.

Why am I getting "Foreign key constraint fails" exception on persist?

Good day, please advise why am I getting following exception. I'm EclipseLink beginner, I'm using jdk1.7.0_05, MySQL server 5.5.25a.
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`stats`.`version`, CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Error Code: 1452
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`stats`.`version`, CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Error Code: 1452
Call: INSERT INTO version (version, activity_id, product, activity_license_id) VALUES (?, ?, ?, ?)
bind => [4 parameters bound]
Query: InsertObjectQuery(cz.ryvo.stats.database.Version[ versionPK=cz.ryvo.stats.database.VersionPK[ product=AP, activityId=0, activityLicenseId=0 ] ])
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:786)
at cz.audatex.audaupdateloader.DatabaseHelper.registerActivity(DatabaseHelper.java:104)
... 3 more
Table License looks like this:
CREATE TABLE `license` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`license` varchar(20) NOT NULL,
`organisation_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `license_UNIQUE` (`license`),
KEY `fk_license_user1` (`user_id`),
KEY `fk_license_organisation1` (`organisation_id`),
CONSTRAINT `fk_license_organisation1` FOREIGN KEY (`organisation_id`) REFERENCES `organisation` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_license_user1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
Table Activity:
CREATE TABLE `activity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`license_id` int(11) NOT NULL,
`time` datetime NOT NULL,
`type` char(1) NOT NULL,
`result` int(1) DEFAULT NULL,
PRIMARY KEY (`id`,`license_id`),
UNIQUE KEY `activity_UQ01` (`license_id`,`time`,`type`),
KEY `fk_activity_license1` (`license_id`),
CONSTRAINT `fk_activity_license1` FOREIGN KEY (`license_id`) REFERENCES `license` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
And table Versions:
CREATE TABLE `version` (
`product` varchar(45) NOT NULL,
`activity_id` int(11) NOT NULL,
`activity_license_id` int(11) NOT NULL,
`version` varchar(45) DEFAULT NULL,
PRIMARY KEY (`product`,`activity_id`,`activity_license_id`),
KEY `fk_version_activity1` (`activity_id`,`activity_license_id`),
CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
My classes I generated in NetBeans using New->Entity Classes from database look like this:
Class Version:
#Entity
#Table(name = "version")
#XmlRootElement
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected VersionPK versionPK;
#Column(name = "version")
private String version;
#JoinColumns({
#JoinColumn(name = "activity_id", referencedColumnName = "id", insertable = false, updatable = false),
#JoinColumn(name = "activity_license_id", referencedColumnName = "license_id", insertable = false, updatable = false)})
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Activity activity;
...
Class VersionPK:
#Embeddable
public class VersionPK implements Serializable {
#Basic(optional = false)
#Column(name = "product")
private String product;
#Basic(optional = false)
#Column(name = "activity_id")
private int activityId;
#Basic(optional = false)
#Column(name = "activity_license_id")
private int activityLicenseId;
...
I'm gettin the exception when I execute following code:
...
ActivityPK apk = new ActivityPK();
apk.setLicenseId(activity.getLicense().getId());
activity.setActivityPK(apk);
em.persist(activity);
em.flush(); <- Here the exception is thrown
...
I suspect it is because activity does not have ID assigned yet and VerionPK uses this ID. Am I right? What is the proper way to persist such data? Should I persist version collection separately after persisting activity with version collection set to null?
Many thanks in advance. Vojtech
Check out JPA 2.0's derived Ids. You can mark the relationship as the ID, or specify that the relationship the id field using maps Id instead of having to manually set the value yourself. This takes care of the problem when creating a new tree and the root entity uses sequencing - the ids aren't available to the children to use as foreign keys until the root is persisted.
Otherwise, the root entity needs to be persisted and flushed so that an Id is assigned. In this case, the Activity entity needs primary key values before you can try and persist a new Version object that reference it since you must manually set all the version.versionpk values.

Java EE 6 JPA 2 ManyToOne Relation Creates Invalid Foreign Key

I am trying to create two entities where both entities have embeddedIds. One of the entities have 2 references to the other entity, where both of those references are related as ManyToOne.
Example codes are written below;
#Embeddable
public class ItemPK {
#Column(nullable = false, length = 100)
private String itemId;
#Column(name = "item_client_id", nullable = false)
private int clientId;
...
}
#Entity
#Table(name = "item")
public class Item {
#EmbeddedId
private ItemPK id;
#ManyToOne
#JoinColumn(name = "item_client_id")
private Client client;
#OneToMany(mappedBy="item", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<RelatedItem> relatedItems;
#OneToMany(mappedBy="relatedItem", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<RelatedItem> relatedItemsRHS;
...
}
#Embeddable
public class RelatedItemPK {
#Column(name = "itemId", length = 100, nullable = false)
private String itemId;
#Column(name = "item_client_id", nullable = false)
private int clientId;
#Column(name = "relatedItemId", length = 100, nullable = false)
private String relatedItemId;
#Column(name = "related_item_client_id", nullable = false)
private int relatedItemClientId;
...
}
#Entity
#Table(name = "related_item")
public class RelatedItem {
#EmbeddedId
private RelatedItemPK id;
#ManyToOne(cascade = CascadeType.ALL, optional = false)
#JoinColumns({
#JoinColumn(name="itemId", referencedColumnName="itemId", insertable=false, updatable=false),
#JoinColumn(name="item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false)
})
private Item item;
#ManyToOne(cascade = CascadeType.ALL, optional = false)
#JoinColumns({
#JoinColumn(name="related_item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false),
#JoinColumn(name="relatedItemId", referencedColumnName="itemId", insertable=false, updatable=false)
})
private Item relatedItem;
...
}
The problem is while creating foreign keys for RelatedItem entity, I got an SQLException. It is the second ManyToOne relation that fails. The foreign key generation sql is below,
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId)
Since item table is indexed first by itemId then by item_client_id, this statement causes MySQL to produce an error.
I would like to switch the places of columns so that the SQL should look like the following,
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_relatedItemId FOREIGN KEY (relatedItemId, related_item_client_id) REFERENCES item (itemId,item_client_id)
I tried changing the order of "JoinColumn"s but the result didn't change. I also tried renaming the fields to check if persistence provider choses the order by column name but again the result didn't change.
So, is there a way to enforce the column ordering?
p.s. I use following stuff:
MySQL 5.1
EclipseLink 2.0.0
Java EE 6
JPA 2
GlassFish v3
Edit: EclipseLink produces following SQL, which fails to run;
CREATE TABLE related_item (SIMILARITY DOUBLE, widget_id INTEGER NOT NULL, relatedItemId VARCHAR(100) NOT NULL, itemId VARCHAR(100) NOT NULL, related_item_client_id INTEGER NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (widget_id, relatedItemId, itemId, related_item_client_id, item_client_id));
CREATE TABLE item (IMAGEURL VARCHAR(2048), STATUS VARCHAR(64), URL VARCHAR(2048), PRICE DOUBLE, STOCK INTEGER, DESCRIPTION TEXT(64000), NAME VARCHAR(255), ITEMID VARCHAR(100) NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (ITEMID, item_client_id));
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_itemId FOREIGN KEY (itemId, item_client_id) REFERENCES item (itemId, item_client_id);
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId);
ALTER TABLE item ADD CONSTRAINT FK_item_item_client_id FOREIGN KEY (item_client_id) REFERENCES client (ID);
Please include the stack trace. However, I strongly recommend you skip the #JoinColumn tags unless you have a VERY good reason for specifying the foreign keys yourself. By specifying the mappedBy attribute in one of the directions, JPA can figure out what to do by itself.
Java EE 6 and JPA put a lot of effort into enabling Convention over Configuration, which means that most of the time, things will work out of the box. It's desirable for you, the programmer because you have less boiler plate code to worry about, and it's desirable for the JPA and Jave EE container implementors because it gives them freedom to chose the best performing solutions. By declaring the foreign key relationships yourself, you rob both you and JPA of this advantage.
Edit: In fact, I suspect that both specifying mappedBy and specifying the #JoinTable could be the root cause of your problem. But I need to see the stack trace to tell for sure.
The order of the columns should not matter. If it does, then you could change the order in your index to match, or change the order you list your primary key in, or just use your scripts to generate your DDL.