I have been searching through different forums for information and I have tried different solutions, but I'm still unable to correct my issue.
I am using hibernate4 annotations for mapping my entities. Auto increment key is not detected when tables are created using hibernate in mysql.
I have the following code:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(unique = true, nullable = false)
private int responseId;
I have also tried:
#Id
#GenericGenerator(name="generator", strategy="increment")
#GeneratedValue(generator="generator")
private int responseId;
With hibernate the id is automatically assigned to a row, but in the mysql table it has no AutoIncrement Constraint. I have to mark field as AI manually. This becomes problematic when I manually insert a record for testing or use jdbc statements for the table. Please let me know what I am missing in configuration that is preventing the hibernate id from assigning an AutoIncrement Contraint.
Use the IDENTITY generator, and use the columnDefinition attribute of #Column to specify the type of the column:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(columnDefinition = "MEDIUMINT NOT NULL AUTO_INCREMENT")
private int responseId;
Related
When I try to make a column value, unique = true I get the following error.
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
alter table student
add constraint UK_fe0i52si7ybu0wjedj6motiim unique (email)" via JDBC Statement
....
....
Caused by: java.sql.SQLSyntaxErrorException: BLOB/TEXT column 'email' used in key specification without a key length
This is my application properties file.
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/dataJpaDB
spring.datasource.username=root
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format_sql=true
server.error.include-message=always
I'm using MySQL version 8.
This is my entity class
#Data
#Entity(name = "Student")
public class Student {
#Id
#SequenceGenerator(
name = "student_sequence",
sequenceName = "student_sequence",
allocationSize = 1
)
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "student_sequence"
)
#Column(
name = "id",
updatable = false
)
private Long id;
#Column(
name = "first_name",
nullable = false,
columnDefinition = "TEXT"
)
private String firstName;
#Column(
name = "last_name",
nullable = false,
columnDefinition = "TEXT"
)
private String lastName;
#Column(
name = "email",
nullable = false,
columnDefinition="TEXT",
unique = true /// this is causing the problem
)
private String email;
#Column(
name = "age",
nullable = false,
columnDefinition = "INTEGER"
)
private Integer age;
public Student(Long id, String firstName, String lastName, String email, Integer age) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.age = age;
}
}
When I remove the "unique = true" everything seems to work fine.
What is causing this problem and how to resolve it.
P.S. sorry for the long post.
When you specify that a field must be unique, Hibernate ORM creates a constraint on the database.
But different databases might have different requirements about the creation of the constraint based on the column definition.
Checking the MySQL website about BLOB and Text types:
For indexes on BLOB and TEXT columns, you must specify an index prefix length.
The easiest solution is not to touch the columnDefinition attribute:
#Column( name = "email",
nullable = false,
unique = true)
private String email
Not sure why you specify it, but you should only use that attribute if you want to define a column using a type that's different from the default used by Hibernate ORM. In this case the column will be a varchar(255) and everything will work fine.
If you want the column to be a TEXT and you still want to create the schema using Hibernate ORM, you could add the constraint creation in the import.sql (and remove the attribute unique=true).
Hibernate ORM will execute the content of that file after the schema has been created and if you include the following query in it, it will create the constraint:
alter table Student add constraint my_unique_constraint unique (email(10))
I will let you to the Hibernate ORM guide for more details about schema generation
Keep in mind that this last solution is not portable and you will have to update the constraint creation query every time you change database (or the attribute name).
PS: I'm talking about Hibernate ORM in this answer but I should have used JPA or Spring Data. Anyway, everything still applies.
I have the following spring-data-jpa entity:
#Entity(name = "absenceDays")
#Table
public final class MyTable {
#EmbeddedId
private MyId myId;
#Column(nullable = false)
private Long anotherId;
}
further, this is the #Embeddable entity used above:
public final class MyId implements Serializable {
#Column(updatable = false, nullable = false)
private Long id;
#Column(updatable = false, nullable = false)
private LocalDate date;
}
I have couple of questions?
Are tables already indexed with their primary keys? It seems to be implementation specific, as discussed here When should I use primary key or index?
How should I index my table with the composite id using the JPA 2.1 #Index annotation, if I need to index my table?
My DB of choice will be AWS RDS with MySQL InnoDB dialect.
Since you tagged the Question [mysql], I will address it from that point of view.
In MySQL the PRIMARY KEY is always UNIQUE and a KEY (aka INDEX). In the case of ENGINE=InnoDB, it is also "clustered" with the data. This makes fetching a row, given the PK, very fast.
To ask questions related to MySQL, it is best to dig below the 3rd party interface (Spring, in your case) to get to the MySQL (or MariaDB or Aurora) info, such as CREATE TABLE and SELECT....
I could probably answer your Q2 with the above info.
I am begginer in Hibernate and i have a table named suffrages1 with no relations to the rest of the database.
The table has an autoincrement identifier field named Suffrages_id.
In the corresponding entity, i am declaring the field as follows :
#Entity(name = "suffrages1")
public class Suffrage1 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#JoinColumn(name = "Suffrages_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
The insertion is fine but when i try to fetch i get this error :Unknown column 'this_.id' in 'field list'
All similar issues i found were about problems with relationships between tables or about correct column names for mapping but as i said this table has no relationship with other table and i think i have the correct names e,g i know that my Java variable in the class is named id but is annotated with #JoinColumn to correspond to the Mysql column. So where did 'this_.id' come from ?
Sorry, i was using #JoinColumn instead of #Column to define the id field.
I have strange error here...
I have two databases configurated on this project, and when i try to save into local mysql repository, i get the title error.
In addition i have remote oracle db in use.
Hibernate:
select
hibernate_sequence.nextval
from
dual
and then
[nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown table 'hibernate_sequence' in field list
and there is no table named hibernate.sequence in database, or attribute in class.
#Id
#GeneratedValue
long id;
#Column(name = "customerid")
private String customerid;
#OneToMany(targetEntity = C_Portfolio.class, fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval=true)
#Fetch(FetchMode.SELECT)
private List<C_Portfolio> portfolios;
#Column(name = "date")
private LocalDate date;
#Column(name = "date_time")
private LocalDateTime datetime;
Furthermore everything seems to be okey just before the save. When i check the class to be saved in debugger mode. it has all the needed values and everything seems to be okey.
You have simply used #GeneratedValue in the POJO, so it tries to find the sequence table. Since you haven't specified the sequence table name, it will look for default sequence table "hibernate_sequence".
For mysql it increments the value by specifying as like below in your POJO:
#GeneratedValue(strategy = GenerationType.AUTO)
If you use it, it will generate a table called hibernate_sequence to provide the next number for the ID sequence.
I know this makes none sense as many tutorials state that you can use SecondaryTable annotation, however it doesn't work in hibernate. I have schema like this:
#Entity
#Table(name="server")
#SecondaryTable(name="cluster", pkJoinColumns = { #PrimaryKeyJoinColumn(name = "uuid", referencedColumnName = "cluster_uuid") })
public class Server {
#Id
#Column(name = "uuid")
private String uuid;
#Column(name = "cluster_uuid")
private String clusterUuid;
#Column(name = "ip", table="cluster")
private String ip;
..... }
#Entity
#Table(name = "cluster")
public class Cluster {
#Id
#Column(name = "uuid")
private String uuid;
#Column(name = "ip")
private String ip;
.....
}
Server.clusterUuid is a foreign key to Cluster.uuid. I am hoping to get Server entity that fetches ip column from Cluster by joining Server.clusterUuid to Cluster.uuid.
Then I was greeted by a hibernate exception:
Caused by: org.hibernate.AnnotationException: SecondaryTable
JoinColumn cannot reference a non primary key
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:402)
at org.hibernate.cfg.annotations.EntityBinder.bindJoinToPersistentClass(EntityBinder.java:620)
at org.hibernate.cfg.annotations.EntityBinder.createPrimaryColumnsToSecondaryTable(EntityBinder.java:612)
I see lots of people encountered this problem. But the first bug for this in Hibernate's bugzilla was 2010, I am surprised it's been there for over two years as this is supposed to be a basic feature. There is some post saying JPA spec only allows primary key to do the mapping, however, I get below from JPA wikibook
JPA allows multiple tables to be assigned to a single class. The
#SecondaryTable and SecondaryTables annotations or
elements can be used. By default the #Id column(s) are assumed to be
in both tables, such that the secondary table's #Id column(s) are the
primary key of the table and a foreign key to the first table. If
the first table's #Id column(s) are not named the same the
#PrimaryKeyJoinColumn or can be used to
define the foreign key join condition.
it's obviously OK for non-primary key. Then I am confused why Hibernate didn't fix this problem as it seems to be easy to implement by a join clause.
anybody knows how to overcome this problem? thank you.
I don't quite understand your setup.
#SecondaryTable is for storing a single entity in multiple tables, but in your case you have a many-to-one relationship between different entities (each one stored in its own table), and it should be mapped as such:
#Entity
#Table(name="server")
public class Server {
#ManyToOne
#JoinColumn(name = "cluster_uuid")
private Cluster cluster;
...
}