Autoincrement in liquibase - java

How do i set the autoincrement property using 'startWith' on a column in PostgreSQL using liquibase??
For some reason it always starts from 1. I tried using a custom sequence but that didn't help either.
<column autoIncrement="true" startWith="100" name="id" type="bigint">
That's my current column definition which does not work.
EDIT:
I want to import data from csv using liquibase. I tried the following:
<changeSet author="author" id="createSequence">
<createSequence
incrementBy="1"
sequenceName="mytable_id_seq"
startValue="1000"/>
</changeSet>
</changeSet>
<changeSet author="author" id="1-mytable">
<createTable tableName="mytable">
<column name="id" type="BIGSERIAL" defaultValueComputed="nextval('mytable_id_seq')">
<constraints primaryKey="true" primaryKeyName="mytable_pkey"/>
</column>
</createTable>
<loadData encoding="UTF-8"
file="liquibase/data/mytable.csv"
separator=","
tableName="mytable">
</loadData>
</changeSet>
If i try this I receive the following error 'currval of sequence "table_id_seq" is not yet defined in this session' and I think that it uses the sequence from the public schema instead of what i have set to liquibase.
Another thing i tried was to update it manually:
ALTER SEQUENCE mytable_id_seq restart with 100;
In this case the sequence used was the one from the public schema, but i want to use the schema set to liquibase

Instead of using bigserial which is an autoincrementing bigint specific to postgres use bigint if you are going to be setting up your own increment and sequence.
"The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases). In the current implementation, specifying:"
CREATE TABLE tablename (
colname SERIAL
);
is the same as
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
From here
https://www.postgresql.org/docs/12/datatype-numeric.html

Related

Liquibase: addForeignKeyConstraint not supported for SQLite

Using the following changeset in liquibase to create a table with a foreign key is possible and works.
<changeSet author="cibn" context="initialSchema" id="initialSchema-edited-1.0.4">
<createTable tableName="prices">
<column name="articleId" type="String">
<constraints nullable="false" foreignKeyName="fk_articles_articleId" references="articles(articleId)"/>
</column>
...
</changeSet>
However, the addForeignKeyConstraint change after creation of the initial schema is not supported.
https://www.liquibase.org/documentation/changes/add_foreign_key_constraint.html
Why? and could this be changed?
I believe that's because ADD CONSTRAINT is not supported by SQLite for ALTER TABLE feature, and that's exactly what Liquibase does during addForeignKeyConstraint change.
Here's the documentation SQL Features That SQLite Does Not Implement
Only the RENAME TABLE, ADD COLUMN, and RENAME COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.

How to add remarks to existing column using liquibase

I'm working in posgresql database, and I want to overwrite an existing comment in a column of a table using liquibase, so I have :
mytable (column1 int) --This is a comment
I know that I can do it in a SQL native way, like this:
<changeSet author="myuser" id="123456">
<sql dbms="postgresql">
COMMENT ON COLUMN mytable.column1 IS 'This is my new comment';
</sql>
</changeSet>
Is there any way to make this change without relying on a native mechanism?
There is a special Change Type setColumnRemarks to add a remark on existing column:
<changeSet author="myuser" id="123456">
<setColumnRemarks
columnName="column1"
remarks="This is my new comment"
tableName="mytable"/>
</changeSet>
You can use the renameColumn Type to liquibase providing the newColumnName the same as the oldColumnName - even thought I am not sure if it will work with PostgreSQL:
<changeSet author="myuser" id="123456">
<renameColumn
newColumnName="column1"
oldColumnName="column1"
remarks="This is my new comment"
tableName="mytable"/>
</changeSet>

Liquibase + Postgresql + Spring Jpa : Id auto increment issue

I have the following Id description in the entity:
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
Liquibase instruction for generate this id is following :
<column name="id" autoIncrement="true" type="INT">
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_entity"/>
</column>
Also I have liquibase scripts that insert to this table predefined values, e.g.
<insert tableName="entityTable" schemaName="public">
<column name="id">1</column>
<!- other fields-->
</insert>
The problem has appeared when I try to insert a new record without id using Jpa repository.
I got an error with a message like "duplicate id".
So, I understand that jpa(hibernate) doesn't use postgresql sequence for getting a new id value. And I don't want to include the sequence name to the entity's id description. I have hoped that this situation could be resolved by the postgresql itself.
And I wouldn't to use the 'hibernate_sequence'.
So, any idea how I can resolve this issue.
Thank you.
Liquibase's instruction autoIncrement="true" generates serial column for PostgreSQL. For serial column PostgreSQL will create a sequence with a name like tablename_colname_seq. Default column values will be assigned from this sequence.
But when you explicitly insert a value into serial column, it doesn't affect sequence generator, and its next value will not change. So it can generate a duplicate value, which is exactly your case.
To prevent this after you inserted explicit values you need to change the current value of a sequence generator either with ALTER SEQUENCE statement or with setval() function, e.g.:
ALTER SEQUENCE tablename_colname_seq RESTART WITH 42;
SELECT setval('tablename_colname_seq', (SELECT max(colname) FROM tablename));
This should fix the issue.
First create to table name example:
CREATE TABLE TABLE_NAME(ID_NAME SERIAL PRIMARY KEY NOT NULL);
Then in your annotation:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long nameAtribute;

Mapping Hibernate : <composite-id> 3

I have a problem mapping to my webapp, I have a table (TacheTicket) contains two primary key and the mapping file I put the following code:
<hibernate-mapping>
<class name="com.model.TacheTicket" table="TACHETICKET">
<composite-id>
<key-property name="idTache" column ="idTache" type="com.model.Tache"/>
<key-property name="idTicket" column="idTicket" type="com.model.Ticket"/>
</composite-id>
</class>
</hibernate-mapping>
but when I execute the program this error appear :
org.hibernate.MappingException: Could not determine type for: com.model.Tache, at table: TACHETICKET, for columns: [org.hibernate.mapping.Column(idTache)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:269)
at org.hibernate.tuple.PropertyFactory.buildStandardProperty(PropertyFactory.java:120)
at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:45)
at org.hibernate.mapping.Component.buildType(Component.java:152)
at org.hibernate.mapping.Component.getType(Component.java:145)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
at org.hibernate.mapping.RootClass.validate(RootClass.java:193)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1108)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1293)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:855)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:774)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1460)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1398)
... 21 more
Table definition.
CREATE TABLE gestionticket.tacheticket (
idTachet INT NOT NULL, idTicket INT NOT NULL,
PRIMARY KEY (idTachet, idTicket), INDEX idTicket_idx (idTicket ASC),
CONSTRAINT idTache FOREIGN KEY (idTachet) REFERENCES gestionticket.tache (idTache) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT idTicket FOREIGN KEY (idTicket) REFERENCES gestionticket.ticket (idTicket) ON DELETE NO ACTION ON UPDATE NO ACTION);
I think you are trying to create many to many relationship between tache and ticket.
You don't need configuration for the third table in hibernate.
You just have to configure the two tables with many-to-many tag.
Checkout this blog.
You need type="int" to agree with the table definition.

Hibernate Identity column but not primary key

I have one sqlserver 2008 r2 datatable, it has one column autoId int identity(1,1), but it's not the primary key, another column varchar(20) is the one.
question is : how do i config the hbm file?
bellow is my config file,but it got errors when i try to save one instance.
"Cannot insert explicit value for identity column in table 'acct_info' when IDENTITY_INSERT is set to OFF."
<property name="autoId" type="int">
<column name="auto_id" not-null="true" unique="true" />
</property>
There can be two reasons , either you don't have sufficient privileges in DB for IDENTITY INSERT or there is mismatch in the mechanism by which you are trying to set an identifier in hibernate and DB layer.
You can have a look at your id generation strategy in hibernate definition file
In DB you can change to Set IDENTITY_INSERT to "ON"
Pick a different generator class

Categories

Resources