I have created an entity with table name and column names.
I have also added the uniquekey constraint for a column name. But when I run, it shows the following error ;
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error
executing DDL "alter table ingredient add constraint
UK_co7ro6kyijhfik027h0y4d3n3 unique (ingredient_name).
java.sql.SQLSyntaxErrorException: Specified key was too long; max key
length is 1000 bytes
After I run the spring boot application, I have tried to add the unique constraint manually in MySQL workbench. - DOES NOT WORK
I have added the below code - DOES NOT WORK
#Table(name = "ingredient", uniqueConstraints=#UniqueConstraint(name="uk_ingredient_name",columnNames="ingredient_name"))
#Column(name = "ingredient_name" ,unique = true)
private String ingredientName;
Tried to create a table manually in Mysql workbench and tried to alter the column name with unique key later. THIS WORKS. But I want hibernate to do this for me.
#Entity
#Table(name = "ingredient")
public class Ingredient {
#Id
#Column(name="ingredient_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "ingredient_name" ,unique = true)
private String ingredientName;
I want to save the ingredients without any repetitions. I do not want duplicate entries.
I have gone through other answers and none of those solutions helped me.
I tried adding length = 20 in the #column.
It works completely fine without any error.
Could you remove
,unique = true
from #Column annotation and try, it seems there is an hibernate bug .When using unique true it does not obey the naming strategy.
For more information look at this post
#UniqueConstraint and #Column(unique = true) in hibernate annotation
and this one
https://hibernate.atlassian.net/browse/HHH-11586
After removing the unique=true I am able to generate the unique constraint with the specified name that is 'uk_ingredient_name'.Since it is already specified in the #Table annotation.
The error you are getting is because hibernate is generating a unique constraint name which is hitting the allowed limit and it is not taking into the account the constraint name you have declared.
#Column(name="username", length=8, unique=true)
worked fine for me.
Related
I am trying to add a unique constraint on a column but it works if I recreate database but doesn't work when I update already existing database.
Similar with adding unique to index. Is there a reason why hibernate doesn't update column if database already exists? I am using Dropwizard.
#Entity
#Table(name = EnrollmentStatusEntity.TABLE_NAME,
indexes = {
#Index(name = Student_RollNo,
columnList = rollNo,
unique = true)
})
#Data
public class Student {
public static final String TABLE_NAME = "Student";
#Id
#NonNull
#Column(name = ID, unique = true, updatable = false, nullable = false)
private String id;
#NonNull
#Column(name = COMPARTMENT_ID, unique=true, nullable = false, updatable = false)
private String rollNo;
Try to add this on your existing Hibernate class
settings.put(Environment.HBM2DDL_AUTO, "update");
it should work with this code but be careful when adding a table to the db if the table isnt NULL then it wont update the db (must be 0 on creating 1st time then change value inside the code or through the browser)
You can control the hibernate's automatic schema generation through your dropwizard project's configuration yaml file:
database:
properties:
hibernate.hbm2ddl.auto: update
This will update the schema automatically every time you run the application, if your db properties are otherwise correctly set in the configuration file.
This is usually not a good idea for production use.
Dropwizard Migrations uses Liquibase to track, version and deploy database changes. I would recommend using Dropwizard Migration and setting hibernate.hbm2ddl.auto: validate, that way you manage the database schema changes with Liquibase and validate with hibernate that the database schema matches the java entities.
I have a MyEntity class with several columns one of which is an auto increment id. MyEntity looks like the following:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Basic(optional = false)
#Column(nullable = false)
private Long id;
When I create a new MyEntity and set all other columns (I do not set the id column), and then call persist:
MyEntity mn = new MyEntity("val1", "val2");
em.getTransaction().begin();
em.persist(mn);
em.getTransaction().commit();
em.close();
the following error occurs:
Query: DataModifyQuery(name="SEQUENCE" sql="UPDATE SEQUENCE SET
SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?")
Caused by: java.sql.SQLSyntaxErrorException: Table/View 'SEQUENCE' does not exist.
I tried to change the strategy of #GeneratedValue with no avail. There are plenty of similar issues online, but with no clear solution what to do in this case.
Do I need to assign a certain value to the id column in my new unmanaged entity? Do I need to setup specific values in the table where the id column is (I only set that it's a primary key)?
Use identity for generating ID by DB:
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
Do not add optional=false, nullable=false. Primary key will be never null in RDBS.
What database are you using?
https://docs.oracle.com/javaee/6/api/javax/persistence/GenerationType.html#AUTO states that the persistence provider will choose the most appropriate solution.
If you are using Hibernate, have you correctly set the dialect explicitly? Oftentimes I've seen Hibernate try to guess the correct dialect but get it wrong. This can cause a domino effect of the AUTO strategy being poorly chosen.
I have Migrated the Springboot version from 1.4.3.RELEASE to 2.1.0.RELEASE in my project. After that CrudRepository.save() always throws org.hibernate.exception.ConstraintViolationException: could not execute statement.
This is what I can see in the Logs :
o.h.e.j.s.SqlExceptionHelper[m: SQL Error: 1062, SQLState: 23000
o.h.e.j.s.SqlExceptionHelper[m: Duplicate entry '11' for key 'PRIMARY'
o.h.i.ExceptionMapperStandardImpl[m: HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement
This is the entity I am trying to save.
#Getter
#Setter
#Entity
#Table(name = "project_m")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "name" , nullable = false)
private String name;
//other fields
}
What has changed from Springboot 1.4.3.RELEASE to 2.1.0.RELEASE is the internal Hibernate version from 5.0 to 5.3.
And what has changed in this is the way the SequenceGenerator works, which is used in case the strategy is GenerationType.AUTO (as is in your case).
Link to hibernate migration doc here.
More details on hibernate generation strategy here.
My guess is there are 2 parallel sessions inserting into this table, and both of them now share a local copy of the sequence number, which creates this collision. Not sure though!
My suggestion would be to change the strategy to GenerationType.SEQUENCE and try.
ConstraintViolationException occurred due to the fact that your primary key constraint for SQL database violates
In SQL the primary key is a unique key to identify the record, the database will throw an exception when you trying to insert a duplicate value to a primary column.
which in turn got by the hibernate and passed to your code and is the reason for this exception.
From Springboot 1.4.3.RELEASE to 2.1.0.RELEASE Hibernate version is updated from 5.0 to 5.3.
The way Hibernate interprets AUTO generation type has changed starting with Hibernate version 5.0
If you use strategy="AUTO", Hibernate will generate a table called hibernate_sequence to provide the next number for the ID sequence. You may have forgotten to add the AutoIncrement feature to your table's PK.
Another way to fix is use following annotations with strategy="AUTO"
#Id
#GeneratedValue(
strategy= GenerationType.AUTO,
generator="native"
)
#GenericGenerator(
name = "native",
strategy = "native"
)
private Long id;
You may use generation strategy strategy="IDENTITY" to enforce using the AutoIncrement feature available in SQL and avoid creating a table.
Pls check here to get some more insights
I got a workaround for this issue by setting a large value in hibernate_sequence table. I saw that the primary key value from the duplicate primary key error is generated from a table named hibernate_sequence.
When we set GenerationType.AUTO in the entity,Hibernate selects the generation strategy based on the Hibernate dialect. In older versions , Hibernate selected the GenerationType.IDENTITY as default for MySQL databases.
It now selects the GenerationType.TABLE which uses a database table to generate primary keys
Method to store entity:
PoolDef poolDef = new PoolDef();
poolDef.setDate_from(date);
poolDef.setName(poolList.getPoolList().get(i).getName());
poolDefRepository.save(poolDef);
Entity itself:
#Setter
#Getter
#EqualsAndHashCode(of = {"Id"})
#Transactional
#Entity
public class PoolDef {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
private String name;
#Column(name = "date_from", columnDefinition = "timestamp with time zone not null")
private OffsetDateTime date_from;
}
The only value that varies is the date_from. I do not know, why new entries are being added to the database and not just get updated. I have the #EqualsAndHashcode that are being built based on primary Id key, so the date_from should not matter. Every method invocation creates a new entry with a completely new Id...
your problem is your
GenerationType.IDENTITY
the documentation says:
Indicates that the persistence provider must assign primary keys for
the entity using a database identity column.
Now the key question is, what SQL is getting generated. Can you please trace the insert SQLs generated?
Also I would prefer to use SEQUENCES of databases. So I do not have to mess around with the Identities of the persistence provider and any application will behave the same against the database if you use the SEQUENCES of databases for your ID/primary key columns.
Also a issue could be your DDL for the table creation, but I assume you know how to define the database tables with the given constraints.
How do I proceed in terms of Hibernate Annotation (JPA) when a table's primary key column is a foreign key to another table with no auto_increment (MySQL).
Thanks.
Something like the following should work (not tested for exact syntax, but should be close):
#Id
private int id;
#OneToOne
#JoinColumn(name = "id", updatable = false, insertable = false)
private RelationEntity other;
You would need to manually set your 'id' field before you persist it, and can't remember if you can set the 'other' entity before the initial save, hibernate may complain if you do that. However, if your 'id' column is set then when you load the entity back out you should have the relationship loaded as well.