How to insert auto_increment in an already created table in liquibase - sql

How to insert auto_increment in an already created table in liquibase?
User table already exists.
<createTable tableName="user">
<column name="user" type="varchar(255)">
<constraint nullable="false">
</column>
<column name="user_id" type="varchar(255)"/>
<column name="password" type="varchar(255)"/>
<column name="email" type="varchar(255)"/>
</createTable>
<addPrimaryKey tableName="user"> columnNames="user" constraintName="user_pk">
Duplicate user occurred in userTable.
The pk was removed because the user could have a duplicate name.
However, since we need to have the value of #Id, if we add the ID and set the autoIncrement, there will be a problem.
<dropPrimaryKey tableName="user"/>
<addColumn tableName="user">
<column name="id" type="BIGINT"/>
</addColumn>
<createSequence
incrementBy="1"
maxValue="9223372036854775807"
minValue="1"
startValue="1"
sequenceName="user_sequence"/>
Error Message
Reason: liquibase.exception.DatabaseException: ERROR: column "id" of relation "user" contains null values [Failed SQL: (0) ALTER TABLE "public"."user" ADD CONSTRAINT "PK_user" PRIMARY KEY ("id")]

Please check this SO post.
<changeSet id="1" author="Me">
<dropPrimaryKey tableName="tv_campaigns"/>
<addColumn tableName="tv_campaigns">
<column name="ID" type="bigint(20)" autoIncrement="true">
<constraints nullable="false" primaryKey="true" unique="true"/>
</column>
</addColumn>
<addAutoIncrement tableName="tv_campaigns" columnName="ID" columnDataType="bigint(20)"/>
</changeSet>
Try using the addAutoIncrement tag, read more about it here.

Related

defining Unique Key in hibernate and how?

<many-to-one name="attachment" class="AttachmentEntity" lazy="false"
fetch="select" cascade="delete">
<column name="SPA_ATTACHMENT_ID" not-null="true" unique-key="IDX_AMT_COND_01"/>
</many-to-one>
What is the Unique Key doing and how will it work as a string?
As per the JBoss documentation,
A unique-key attribute can be used to group columns in a single,
unique key constraint. The attribute overrides the name of any
generated unique key constraint.
Typical use case for unique-key would be, when you want the values of multiple columns as a whole to be unique.
For example:
class Department {...}
class Employee {
Integer employeeId;
Department department;
}
So, to ensure that 2 Employee objects with same employeeId and department are not persisted, we can use the unique-key attribute with same value EmpIdDept on the 2 columns EMP_ID and DEPT_ID to enforce the uniqueness constraint on them as a whole:
<property name="employeeId" column="EMP_ID" unique-key="EmpIdDept"/>
<many-to-one name="department" column="DEPT_ID" class="Department" unique-key="EmpIdDept"/>
The string specified as the attribute value, i.e. IDX_AMT_COND_01 in your case, is just the name of the multi column unique constraint.
Also check this answer and this one (to achieve the same using #UniqueConstraint)
NOTE: to use single column unique constraint, you need to use
unique="true"

Liquibase for/for each operation (migrating table data)

I'm using Liquibase and I need to insert data in one table, depending on the entries in another (create a foreign key reference)
Table: Entities (currently empty)
PK id
INT data
Table: Existing_table (contains data)
PK id
... data
FK entities_id (references Entities.id)
for each entry in Existing_table I need to insert a value in Entities and update entities_id in Existing_table, using the created Entities.id key.
How can I achieve this?
Couldn't find a way to make a parametrised loop, so used a temopary column for storing referenced id.
<changeSet id="add temp_column to Entities" author="">
<addColumn tableName="Entities">
<column name="temp_id" type="BIGINT"></column>
</addColumn>
</changeSet>
<changeSet author="" id="insert Existing_table keys into Entities">
<sql>
INSERT INTO Entities(type_id, temp_id)
select 1, id
from Existing_table;
</sql>
</changeSet>
<changeSet author="" id="insert entity keys into Existing_table">
<sql>
UPDATE Existing_table d set entity_id = ent.id
FROM (select id, temp_id
from Entities) ent
where ent.temp_id = d.id;
</sql>
</changeSet>
<changeSet id="drop temp_column to Entities" author="">
<dropColumn tableName="Entities"
columnName="temp_id"/>
</changeSet>
<changeSet author="" id="addNotNullConstraint Existing_table-Entities">
<addNotNullConstraint columnDataType="BIGINT"
columnName="entity_id"
tableName="Existing_table"/>
</changeSet>

Mapping composite key to two foreign keys

I've got the following two tables:
Jobs
--------
JobNo
DivisionID
NCRs
--------
ID
JobNo
SpoilageJobNo
DivisionID
JobNo and DivisionID make up a composite key in the Jobs table (I know, but unfortunately it has to be a composite key, as it's actually a view that's pulling data from 4 different databases), and I need to join this key to the NCRs table on both JobNo and SpoilageJobNo.
I've tried the following mappings:
<class name="Job" table="v_Jobs">
<composite-id name="Key">
<key-property name="JobNo"></key-property>
<key-many-to-one name="Division" class="Division" column="DivisionID"/>
</composite-id>
<bag name="NCRs">
<key>
<column name="JobNo"></column>
<column name="DivisionID"></column>
</key>
<one-to-many class="NCR"/>
</bag>
<bag name="SpoilageNCRs">
<key>
<column name="SpoilageJobNo"></column>
<column name="DivisionID"></column>
</key>
<one-to-many class="NCR"/>
</bag>
</class>
<class name="NCR" table="NCRs">
<id name="ID">
<generator class="identity"></generator>
</id>
<many-to-one name="Division"
class="Division"
column="DivisionID">
</many-to-one>
<many-to-one name="Job"
class="Job"
column="JobNo">
</many-to-one>
<many-to-one name="SpoilageJob"
class="Job"
column="SpoilageJobNo">
</many-to-one>
</class>
But I just get the error Foreign key (FK480F1031931B2CA4:NCRs [JobNo])) must have same number of columns as the referenced primary key (v_Jobs [JobNo, DivisionID])
This is the answer Tom posted to his question:
Ah ha, think I've got it. I've updated my mappings for the NCR with this:
<many-to-one name="Job" class="Job">
<column name="JobNo"></column>
<column name="DivisionID"></column>
</many-to-one>
<many-to-one name="SpoilageJob" class="Job">
<column name="SpoilageJobNo"></column>
<column name="DivisionID"></column>
</many-to-one>

Joining Tables with Composite Primary Keys in Hibernate hbm files

I have two table to be joined using hbm file.
The scenario is as follows
Table B has a composite PK.
Table B
a1 (pk)
a2 (pk)
a3 (pk)
foo
bar
========
Table A has a primary key and is a foreign key from Table B
Table A
a1 (pk,fk)
hip
hop
========
This a one to many relation from Table A to B.
Can any one help me out with the hbm file mapping?
I am jotting down wot i have tried.
For Table B
<class>
<composite-id name="XXXX" class=".....">
<key-property name="a1" column="a1" type="int"/>
<key-property name="a2" column="a2" type="int"/>
<key-property name="a3" column="a3" type="int"/>
</composite-id>
<property name="foo" column="foo" type="java.lang.Float"></property>
<property name="bar" column="bar" type="java.lang.Float"></property>
</class>
For Table A
Normal hibernate mapping.
How to join both tables?
a workaround could be afake propertyref to break out of the compositeId
<class class="B">
<property name="a1_again" column="a1" insert="false" update="false"/>
<bag name="As" class="A">
<key property-ref="a1_again"></key>
...
</bag>
</class>

How do I make a self-referencing many-to-many relationship in Fluent NHibernate mapping?

Can someone tell me how to accomplish this mapping using Fluent NHibernate? It's simply an account table with a composite key, that has many child accounts in a conjunction table.
Here's the working NHibernate mapping and the create SQL it generates:
<?xml version="1.0"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
<class name="NHibernateM2M000.Account, NHibernateM2M000" lazy="false">
<composite-id>
<key-property type="Int32" name="AccountId" />
<key-property type="Char" name="AccountTypeAbbr" />
</composite-id>
<property name="Name" column="AccountName" />
<bag name="ChildAccounts" lazy="false" table="AccountXref">
<key>
<column name="ParentAccountId" sql-type="int" />
<column name="ParentAccountTyper" sql-type="nchar" length="1" />
</key>
<many-to-many class="NHibernateM2M000.Account, NHibernateM2M000">
<column name="ChildAccountId" sql-type="int"/>
<column name="ChildAccountType" sql-type="nchar" length="1" />
</many-to-many>
</bag>
</class>
create table Account (AccountId INT not null, AccountTypeAbbr NCHAR(1) not null, AccountName NVARCHAR(255) null, primary key (AccountId, AccountTypeAbbr))
create table AccountXref (ParentAccountId int not null, ParentAccountTyper nchar not null, ChildAccountId int not null, ChildAccountType nchar not null)
alter table AccountXref add constraint FKB769F8B52F1320AB foreign key (ChildAccountId, ChildAccountType) references Account
alter table AccountXref add constraint FKB769F8B5A2DB3DC7 foreign key (ParentAccountId, ParentAccountTyper) references Account
I believe after looking at Fluent NHibernate at the time of this posting and now, that it's not possible. Dropping into the .hbm file is the only way to accomplish what I wanted here.