JPA insert identity id starts at 0 instead of 1? - java

I have a problem when I am inserting an new entity to a table in SQL Server, even when I set these annotation for my PK entity in java code.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
The index still started at 0, this case always happens when I drop and re-create table (when identity is set to null) and use insert by JPA repository. (index start at 1 when I used insert statement at Microsoft SSMS).
But when I delete table's data and use DBCC CHECKIDENT ('table', RESEED, 0);, then index of inserted record is 1.
Here is my CREATE statement:
CREATE TABLE [dbo].[tbl_member_info](
[id] [int] IDENTITY(1,1) NOT NULL,
[type] [int] NULL,
[id_card_number] [varchar](20) NULL,
[prefix] [int] NULL,
[first_name] [nvarchar](30) NULL,
[last_name] [nvarchar](30) NULL,
[dob] [datetime] NULL,
[email_personal] [varchar](70) NULL
)
Could anyone help me solve this problem?

Related

Spring Hibernate SQL Server - problem in updating columns

I get the below error while not updating the mentioned column at all. I only update two another columns that one of them is used to compute the column "Available".
The column "Available" cannot be modified because it is either a computed column or is the result of a UNION operator.
I also used native query (as below) to be sure that there is no problem during translating hql to sql, but the problem still exists
query = session.createQuery("update Retail.Account SET Balance = Balance + :Amount, RowVersion = RowVersion + 1 WHERE RowVersion = :RowVersion AND Id = :Id")
Here is my model(table) definition:
#Entity
#Table(name = "Account", schema = "Retail")
public class Account {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "Id")
public Integer Id;
// ..... some attributes
#Column(name = "Balance")
public BigDecimal Balance; // the column that I want to update
#Column(name = "Available")
public BigDecimal Available;// the computed column in my error
// ......
#Version
#Column(name = "RowVersion")
public Long RowVersion;
}
My hibernate Configuration is as below:
hibernate.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.url=########
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.username=**************
hibernate.password=**************
hibernate.hbm2ddl.auto=none
hibernate.setConnectionCachingEnabled=true
hibernate.show_sql=false
hibernate.format_sql=true
Also my table definition in SQL Server is as below:
CREATE TABLE [Retail].[Account](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CustomerId] [int] NOT NULL,
[AccountTypeId] [int] NOT NULL,
[OpeningDate] [datetime] NOT NULL,
[StatusId] [int] NOT NULL,
[Balance] [decimal](18, 2) NOT NULL,
[Credit] [decimal](18, 2) NOT NULL,
[Blocked] [decimal](18, 2) NULL,
[Available] AS (([Balance]+[Credit])-[Blocked]),
[RowVersion] [bigint] NOT NULL,
CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED
([Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
My problem was solved when I added #Generated tag as below:
#Generated( value = GenerationTime.ALWAYS )
#Column(name = "Available")
public BigDecimal Available;
But I can't understand why ?!!! (because it does not seem to be mandatory specially when I use native query)

MySQL. When trying to delete few duplicate rows, it deletes the last and does not delete any further

I've got tables Artist, Concert, and Artist_Concert, which contains many-to many connections between Artist and Concert.
The problem is: after adding a Concert with few Artists, when trying to delete rows from Artist_Concert, it only deletes only one row and nothing happens when trying to delete any others.
This is how I'm trying to delete rows in Java:
stat = connect.createStatement();
res = stat.executeQuery ("SELECT idConcert FROM concerthall.concert where ConcertName = '"+conc+"';");
res.first();
int idconc = res.getInt(1);
stat.execute ("DELETE FROM concerthall.artist_concert WHERE idConc="+idconc+"");
Artist
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist` (
`idArtist` INT NOT NULL AUTO_INCREMENT,
`ArtName` VARCHAR(45) NOT NULL,
`ArtFee` INT NULL,
PRIMARY KEY (`idArtist`))
ENGINE = InnoDB
Artist-Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist_Concert` (
`idCA` INT NOT NULL AUTO_INCREMENT,
`idArt` INT NOT NULL,
`IdConc` INT NOT NULL,
INDEX `idart_idx` (`idArt` ASC),
INDEX `idconc_idx` (`IdConc` ASC),
PRIMARY KEY (`idCA`),
CONSTRAINT `idart2`
FOREIGN KEY (`idArt`)
REFERENCES `concerthall`.`Artist` (`idArtist`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `idconct4`
FOREIGN KEY (`IdConc`)
REFERENCES `concerthall`.`Concert` (`idConcert`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Concert` (
`idConcert` INT NOT NULL AUTO_INCREMENT,
`ConcertName` VARCHAR(45) NOT NULL,
`ConcertDateTime` DATETIME NOT NULL,
`Organizator` INT NOT NULL,
PRIMARY KEY (`idConcert`),
INDEX `concertorg_idx` (`Organizator` ASC),
CONSTRAINT `concertorg`
FOREIGN KEY (`Organizator`)
REFERENCES `concerthall`.`Organizator` (`idOrganizator`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
The easiest way to drop duplicates is:
ALTER IGNORE TABLE table ADD UNIQUE INDEX( a, b );
In the INDEX() part, enter the name(s) of the column(s) you only want unique entries for. I think you want:
ALTER IGNORE TABLE concerthall.artist_concert ADD UNIQUE INDEX( idConc );
Then drop the index.

After the Migration play 2.4, use an existing sequence of the postgresdb to generate the id of Play-2.4 Entity

We have been using Play 2.3.9 and we are now migrating to Play 2.4.1 When I use the old version of Play saving an Entity works but with the new verion the Id is not generated.
If I use,
#GeneratedValue(strategy = GenerationType.SEQUENCE)
it's working fine, but when am using,
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
in Model getting below Exception
[error] p.c.s.n.PlayDefaultUpstreamHandler - Cannot invoke the action
javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[ERROR: null value in column "id" violates not-null constraint\n Detail: Failing row contains (null, null, kumar, null, 9581672143, kumar#gmail.com, +j+b2lc5C7B48IGct2+L1jKBEIXhl0aOYy1BOnb85/Q=, iCZqST2EU4ECVaPwzGxr1hZ/b4Da34BI/C9xKCbpo78=, null, null, null, f, f, null, BLOOD_BANK_ADMIN, null, f, f, null, null, null, null, t, f, 2015-08-03 15:53:47.308, 2015-08-03 15:53:47.309, null, null, null, null, null, null, null, f, null).]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:90) ~[avaje-ebeanorm-4.6.2.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:57) ~[avaje-ebeanorm-4.6.2.jar:na]
at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeInsertBean(DefaultPersistExecute.java:59) ~[avaje-ebeanorm-4.6.2.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:446) ~[avaje-ebeanorm-4.6.2.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:480) ~[avaje-ebeanorm-4.6.2.jar:na]
Any suggestions?
Since ebean 4.0.5, id genration strategy has changed from IDENTITY to GENERATOR.
workaround: Play Framework 2.4 Ebean Id Generation

Hibernate Duplicate entry '7090' for key 'PRIMARY'

Im getting following error when the application tries to insert a record row in the db.
SQL Error: 1062, SQLState: 23000
ERROR org.hibernate.util.JDBCExceptionReporter - Duplicate entry '7089' for key 'PRIMARY'
ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
Caused by: java.sql.BatchUpdateException: Duplicate entry '7090' for key 'PRIMARY'
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1269)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:955)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
The definition is
#Id
#Column(name = "CST_CUSTOMER_ID_PK")
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
The part at which the error occurs is :
savedCustomer = customerDao.save(customer);
mtmrsLogger.debug("saved customer id:" + savedCustomer.getId());
/**
* Updating Customer Trans Table
*/
updateCustomerTransForMakerChecker(customer, customerform.getAuditDetails());
/**
* Updating Customer Audit
*/
updateCustomerAuditForMakerChecker(customer, customerform.getAuditDetails());
//status=1;
//Add customer ewallet account
updateCustomerInWalletBalance(customer, customerform.getAuditDetails());
//send sms to customer
smsManager.sendSMSToCUCustomer(customer.getMobileno(), userBean);
}
mtmrsLogger.exiting("CustomerManagerImpl", "addCustomer");
My log shows, program has reached ' Exiting Class: CustomerManagerImpl Method: addCustomer' this part. Im saving the customer ,im setting the same entry in other two tables. The primary key of customer table is foreigh key in other two tables. Im lost please help.
CREATE TABLE `CST_CUSTOMER_INFO` (
`CST_CUSTOMER_ID_PK` bigint(11) NOT NULL AUTO_INCREMENT,
`CST_MOBILE` varchar(30) DEFAULT NULL,
`CST_FIRST_NAME` varchar(50) DEFAULT NULL,
`CST_LAST_NAME` varchar(150) NOT NULL,
`CST_MIDDLE_NAME` varchar(50) DEFAULT NULL,
PRIMARY KEY (`CST_CUSTOMER_ID_PK`)
) ENGINE=InnoDB AUTO_INCREMENT=4103 DEFAULT CHARSET=latin1
Im getting error occassionally in production , but in local its ok..
As table is being modified by more than one application, use of #GenericGenerator(name = "generator", strategy = "increment") will result in ambiguity.
Explanation
Strategy increment : It generates identifiers of type long, short or
int that are unique only when no other process is inserting data into
the same table. It should not be used in the clustered environment.
So you should rethink what strategy is to be used to generate id's. Using sequence or native strategy can resolve your problem.
Replace
`CST_CUSTOMER_ID_PK` bigint(11) NOT NULL AUTO_INCREMENT,
with
`CST_CUSTOMER_ID_PK` bigint(11) NOT NULL,
You are incrementing the id using hibernate/java, no need to make the DBMS increment it also.

JPA joined column allow every value

I'm testing JPA, in a simple case File/FileVersions tables (Master/Details), with OneToMany relation, I have this problem: in FileVersions table, the field "file_id" (responsable for the relation with File table) accepts every values, not only values from File table.
How can I use the JPA mapping to limit the input in FileVersion.file_id only for values existing in File.id?
My class are File and FileVersion:
FILE CLASS
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="FILE_ID")
private Long id;
#Column(name="NAME", nullable = false, length = 30)
private String name;
//RELATIONS -------------------------------------------
#OneToMany(mappedBy="file", fetch=FetchType.EAGER)
private Collection <FileVersion> fileVersionsList;
//-----------------------------------------------------
FILEVERSION CLASS
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="VERSION_ID")
private Long id;
#Column(name="FILENAME", nullable = false, length = 255)
private String fileName;
#Column(name="NOTES", nullable = false, length = 200)
private String notes;
//RELATIONS -------------------------------------------
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="FILE_ID", referencedColumnName="FILE_ID", nullable=false)
private File file;
//-----------------------------------------------------
and this is the FILEVERSION TABLE
CREATE TABLE `JPA-Support`.`FILEVERSION` (
`VERSION_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`FILENAME` varchar(255) NOT NULL,
`NOTES` varchar(200) NOT NULL,
`FILE_ID` bigint(20) NOT NULL,
PRIMARY KEY (`VERSION_ID`),
KEY `FK_FILEVERSION_FILE_ID` (`FILE_ID`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
Thanks for help,
I know the SQL constraint to limit the input, but it is possible to create this SQL costraint using some annotation, without writing by hand the SQL in the database?
I'm new on JPA, I was thinking that using #JoinColumn annotation, JPA could create also the costraint...
Thank you again.
At the Java level, you describe and annotate associations between classes - which and you did - and your mapping looks fine.
At the database level, if you want to restrict the possible values in the file_id column to values that are primary keys in the FILE table, you should use a foreign key constraint. To do so, you will need to use InnoDB tables. Something like that:
CREATE TABLE `JPA-Support`.`FILEVERSION` (
`VERSION_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`FILENAME` varchar(255) NOT NULL,
`NOTES` varchar(200) NOT NULL,
`FILE_ID` bigint(20) NOT NULL,
PRIMARY KEY (`VERSION_ID`),
FOREIGN KEY `FK_FILEVERSION_FILE_ID` (`FILE_ID`) REFERENCES FILE(ID)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
The table FILE also has to use InnoDB. Actually, use InnoDB tables for the tables for which you want to use referential integrity.

Categories