It seems to be a common error. I've seen other topics, but nothing changed. Here is MySQL script:
DROP DATABASE IF EXISTS `library`;
CREATE DATABASE IF NOT EXISTS `library`;
USE `library`;
SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT;
SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS;
SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION;
SET NAMES utf8;
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE customer
(
c_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name CHAR(50) NOT NULL,
last_name CHAR(50) NOT NULL,
email CHAR(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO customer VALUES
(1,'David','Bush','bushd#gg.com'),
(2,'John','Doe','johnd#gg.com'),
(3,'Max','Rao','maxr#gg.com'),
(4,'Mary','James','maryj#gg.com'),
(5,'Tony','Lord','tony#gg.com');
CREATE TABLE rental
(
rental_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
issue_date DATE,
return_date DATE,
customer_id INT,
book_id INT,
KEY `FK_CUSTOMER_idx` (`customer_id`),
CONSTRAINT `FK_CUSTOMER`
FOREIGN KEY (`customer_id`)
REFERENCES `customer` (`c_id`),
KEY `FK_BOOK_idx` (`book_id`),
CONSTRAINT `FK_BOOK`
FOREIGN KEY (`book_id`)
REFERENCES `book` (`b_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO rental VALUES
(1,'2014-10-11',null,3,1),
(2,'2014-10-11',null,5,2);
CREATE TABLE book
(
b_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
author CHAR(50) NOT NULL,
title CHAR(100) NOT NULL,
category CHAR(50) NOT NULL,
availability CHAR(5) NOT NULL DEFAULT 'yes'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO book VALUES
(1,'Doyle','The adventures of binkle and flip','Child','no'),
(2,'Blyton','The adventures of sherlock holmes','Crime fiction','no'),
(3,'Rustard','Insects','Science','yes'),
(4,'Larsson','Man who hate woman','Crime','yes'),
(5,'Tolkien','Lord of the Rings: The Two Towers','Fantasy','lost');
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION;
SET SQL_NOTES=#OLD_SQL_NOTES;
SET FOREIGN_KEY_CHECKS=1;
Here is the error:
ERROR: Cannot add or update a child row: a foreign key constraint fails
(`library`.`rental`, CONSTRAINT `FK_BOOK` FOREIGN KEY (`book_id`) REFERENCES
`book` (`b_id`))
Rental entity:
#Entity
#Table(name="rental")
public class Rental {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="rental_id")
private int id;
#Column(name="issue_date")
private Date issueDate;
#Column(name="return_date")
private Date returnDate;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name="book_id", referencedColumnName="b_id")
private Book book;
#ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name="customer_id", referencedColumnName="c_id")
private Customer customer;
Customer entity:
#Entity
#Table(name="customer")
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="c_id")
private int id;
#NotNull
#Column(name="first_name")
private String firstName;
#NotNull
#Column(name="last_name")
private String lastName;
#Email
#Column(name="email")
private String email;
#OneToMany(mappedBy="customer")
private List<Rental> rentals;
Book entity:
#Entity
#Table(name="book")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="b_id")
private int id;
#NotNull
#Column(name="author")
private String author;
#NotNull
#Column(name="title")
private String title;
#NotNull
#Column(name="category")
private String category;
#NotNull
#NotEmpty
#Column(name="availability")
private String availability;
#OneToMany(mappedBy="book")
private List<Rental> rentals;
Controller(values hardcoded for testing):
#PostMapping("/confirmRent")
public String confirmRent(/*PathVariable ("customerId") int cId,
#PathVariable ("bookId") int bId*/) {
int cId = 5;
int bId = 5;
Customer theCustomer = customerService.getCustomer(cId);
Book theBook = bookService.getBook(bId);
rentalService.createNewEntry(theCustomer, theBook);
return "redirect:/book/allAvailableBooks";
}
DAO :
#Override
public void createNewEntry(Customer theCustomer, Book theBook) {
Session currentSession = sessionFactory.getCurrentSession();
Rental rental = new Rental();
rental.setBook(theBook);
rental.setCustomer(theCustomer);
currentSession.save(rental);
}
Am I missing something out? PS: The code may look amateurish: I'm a beginner ;)
Hi All creating one to many realtionship.
I have 2 table one is Emp and other is Project.
One Emp can have many Project.
These are my bean class.
public class Emp {
public List<Project> getProjectList() {
return projectList;
}
public void setProjectList(List<Project> projectList) {
this.projectList = projectList;
}
#Generated(value = { "id" })
#Id
private int id;
#Column(name="name")
private String name;
#Column(name="city")
private String city;
#OneToMany( cascade=CascadeType.ALL , fetch=FetchType.LAZY, mappedBy="emp",orphanRemoval=true)
private List<Project> projectList=new ArrayList<Project>();
public void addProject(Project project) {
this.projectList.add(project);
if (project.getEmp() != this) {
project.setEmployer(this);
}
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
This is the project class
#Entity
public class Project {
#Generated(value = { "id" })
#Id
private int id;
#Column(name="name")
private String name;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="empid", nullable=false)
private Emp emp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Emp getEmp() {
return emp;
}
public void setEmp(Emp emp) {
this.emp = emp;
}
public void setEmployer(Emp emp2) {
this.emp = emp2;
if (!emp2.getProjectList().contains(this)) { // warning this may cause performance issues if you have a large data set since this operation is O(n)
emp.getProjectList().add(this);
}
}
}
This is my code to save the parent and child
public class MainTest {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.addAnnotatedClass(org.hibernate.model.Emp.class);
configuration.addAnnotatedClass(org.hibernate.model.Project.class);
configuration.addAnnotatedClass(org.hibernate.model.Stu.class);
configuration.addAnnotatedClass(org.hibernate.model.Address.class);
configuration.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/test");
configuration.setProperty("hibernate.connection.password", "123456789");
configuration.setProperty("hibernate.connection.username", "root");
configuration.setProperty("hibernate.show_sql", "true");
configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
org.hibernate.Transaction transaction =session.beginTransaction();
Emp emp = new Emp();
emp.setCity("nagaland");
emp.setName("divyffa");
Project project1=new Project();
project1.setName("dotedxvc");
emp.addProject(project1);
session.save(emp);
transaction.commit();
session.close();
}
}
These is the structure of my table
CREATE TABLE `emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
CREATE TABLE `project` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`empid` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `forgn-project_idx` (`empid`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;
Whenever I save my Parent class my child class also get saved but the empid column value is getting saved as 0. Each time it is getting saved as 0.
Please I Don't know what is the issue and thanks for the help.
I have Search about this issue but not find any result.
It seem to be that you have set only one side of relationship.
I think some thing like below need here
project1.setEmp(emp);
I think your FOREIGN KEY column should refer to the parent table means "emp" table PRIMARY KEY column. I have modified child table means "project" structure like-
CREATE TABLE `project` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`empid` int(11) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (empid) REFERENCES emp (id)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;
In Emp entity class add #OneToMany mapping as-
#OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL,mappedBy="emp")
private List projectList;
and also in Project entity class modify #ManyToOne mapping as-
#ManyToOne(optional = false)
#JoinColumn(name = "empid", insertable = true)
private Emp emp;
I guess this will work for you.
I am using JPA with Hibernate 4.x., and postgresql 9.x, but I wonder some problem.
When using #ElementCollection annotation, and I configured Set type embedded field, I expect to generate Primary key of embeddable Collection Table, but it's not working. I can find just one foreign key against owner of relationship. i wonder why do not it generate primary key. This is my test code.
A.java
#Entity
public class A {
#Id
private Long id;
#Column(name = "\"as\"")
private String as;
public String getAs() {
return as;
}
public void setAs(String as) {
this.as = as;
}
#ElementCollection
private Set<B> bs = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<B> getBs() {
return bs;
}
public void setBs(Set<B> bs) {
this.bs = bs;
}
}
B.java
#Embeddable
public class B {
private String col1;
private String col2;
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
the result is
Hibernate:
create table A (
id int8 not null,
"as" varchar(255),
primary key (id)
)
Hibernate:
create table A_bs (
A_id int8 not null,
col1 varchar(255),
col2 varchar(255)
)
Hibernate:
alter table A_bs
add constraint FK_rcecll1ao3brmwwnsep3iqq3p
foreign key (A_id)
references A
Let me know why it did not generate primary key?
Thanks in advance~
Because #ElementCollection is used for mapping collections of simple elements, which is not the same as entities. The only thing they need is a reference to owning entity which is properly generated by Hibernate (column A_id and foreign key (A_id) references A). Take a look at this post for more information.
If you really need a primary key in the embeddable object, consider making it a proper entity.
To generate a primary key for an embeddable collection like Set need to mark all columns of embeddable class with annotation #Column(nullable = false), due to requirement that nullable fields could not be a part of composite primary key
I am trying to learn hibernate. I have a movie table with a foreign key to a genre table. Each movie is assigned to a single genre. Each genre may be assigned to many movies.
Here are the table definitions:
CREATE TABLE `movie` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(64) NOT NULL,
`genre_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_genre` (`genre_id`),
CONSTRAINT `fk_genre` FOREIGN KEY (`genre_id`) REFERENCES `genre` (`id`) ON UPDATE CASCADE,
)
CREATE TABLE IF NOT EXISTS `genre` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
)
For code I have
#Entity
public class Movie implements java.io.Serializable {
private static final long serialVersionUID = 1;
private Integer id;
private String title;
private Genre genre;
...
#ManyToOne
public Genre getGenre() {
return genre;
}
Also
#Entity
public class Genre implements java.io.Serializable {
private static final long serialVersionUID = 1;
private Integer id;
private String name;
#Id
#GeneratedValue
#Column(name = "id")
public Integer getId() {
return this.id;
}
Then the select generated by hibernate looks like
select
movie0_.id as column1_4_,
movie0_.genre_id as genre11_4_,
movie0_.title as title4_
from
Movie movie0_
And this not right as there's no reference to the genre table. The correct query should have a join with the genre table. More like
select
movie0_.id as column1_4_,
genre.name as genre11_4_,
movie0_.title as title4_
from
Movie movie0_, Genre genre
where
movie0_.genre_id = genre.id;
I'm a little bit of a loss as to what I'm doing wrong. Should the many to one annotation be in the Genre class instead of the Movie class? Or do you see anything else that I'm doing wrong?
Based on the advise below, Movie now has
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id).append(" ");
sb.append(title).append(" ");
this.getGenre(); //new
sb.append(genre.getName());
return sb.toString();
}
#ManyToOne(fetch=FetchType.EAGER) //new
public Genre getGenre() {
return genre;
}
And the way I'm loading Movie is through
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
List<Movie> movies = session.createQuery("from Movie").list();
for (Movie movie : movies) {
System.out.println(movie.toString());
}
session.close();
}
What I'm seeing is that even though I have the eager load and I'm explicitly saying getGenre in toString, no query is generated and I'm just getting a null back.
When you use HQL syntax (e.g. createQuery("from Movie")), then Hibernate/JPA will only fetch the Genre entity when you call getGenre() on your Movie object. This is called "lazy fetching". When the method is called, Hibernate will issue another query to fetch the Genre.
Note that HQL queries ignore the FetchType on your annotations - HQL is used to tell Hibernate exactly what to do, rather than using the hints in the annotations.
To make it fetch the Genre in the same query as the Movie, you need to tell it to:
createQuery("from Movie m join fetch m.genre")
try this:
Moive side:
#ManyToOne
#JoinColumn(name = "genre_id")
public Genre getGenre() {..}
and on the other side (genre):
#OneToMany(mappedBy="genre")
List/Set getMovies(){..}
then you can from a movie object movie.getGenre() get Genre.
I'm facing what I think is a simple problem with Hibernate, but can't solve it (Hibernate forums being unreachable certainly doesn't help).
I have a simple class I'd like to persist, but keep getting:
SEVERE: Field 'id' doesn't have a default value
Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not insert: [hibtest.model.Mensagem]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
[ a bunch more ]
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
[ a bunch more ]
The relevant code for the persisted class is:
package hibtest.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Mensagem {
protected Long id;
protected Mensagem() { }
#Id
#GeneratedValue
public Long getId() {
return id;
}
public Mensagem setId(Long id) {
this.id = id;
return this;
}
}
And the actual running code is just plain:
SessionFactory factory = new AnnotationConfiguration()
.configure()
.buildSessionFactory();
{
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
Mensagem msg = new Mensagem("YARR!");
session.save(msg);
tx.commit();
session.close();
}
I tried some "strategies" within the GeneratedValue annotation but it just doesn't seem to work. Initializing id doesn't help either! (eg Long id = 20L).
Could anyone shed some light?
EDIT 2: confirmed: messing with#GeneratedValue(strategy = GenerationType.XXX) doesn't solve it
SOLVED: recreating the database solved the problem
Sometimes changes made to the model or to the ORM may not reflect accurately on the database even after an execution of SchemaUpdate.
If the error actually seems to lack a sensible explanation, try recreating the database (or at least creating a new one) and scaffolding it with SchemaExport.
If you want MySQL to automatically produce primary keys then you have to tell it when creating the table. You don't have to do this in Oracle.
On the Primary Key you have to include AUTO_INCREMENT. See the example below.
CREATE TABLE `supplier`
(
`ID` int(11) NOT NULL **AUTO_INCREMENT**,
`FIRSTNAME` varchar(60) NOT NULL,
`SECONDNAME` varchar(100) NOT NULL,
`PROPERTYNUM` varchar(50) DEFAULT NULL,
`STREETNAME` varchar(50) DEFAULT NULL,
`CITY` varchar(50) DEFAULT NULL,
`COUNTY` varchar(50) DEFAULT NULL,
`COUNTRY` varchar(50) DEFAULT NULL,
`POSTCODE` varchar(50) DEFAULT NULL,
`HomePHONENUM` bigint(20) DEFAULT NULL,
`WorkPHONENUM` bigint(20) DEFAULT NULL,
`MobilePHONENUM` bigint(20) DEFAULT NULL,
`EMAIL` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
Here's the Entity
package com.keyes.jpa;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigInteger;
/**
* The persistent class for the parkingsupplier database table.
*
*/
#Entity
#Table(name = "supplier")
public class supplier implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
**#GeneratedValue(strategy = GenerationType.IDENTITY)**
#Column(name = "ID")
private long id;
#Column(name = "CITY")
private String city;
#Column(name = "COUNTRY")
private String country;
#Column(name = "COUNTY")
private String county;
#Column(name = "EMAIL")
private String email;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "HomePHONENUM")
private BigInteger homePHONENUM;
#Column(name = "MobilePHONENUM")
private BigInteger mobilePHONENUM;
#Column(name = "POSTCODE")
private String postcode;
#Column(name = "PROPERTYNUM")
private String propertynum;
#Column(name = "SECONDNAME")
private String secondname;
#Column(name = "STREETNAME")
private String streetname;
#Column(name = "WorkPHONENUM")
private BigInteger workPHONENUM;
public supplier()
{
}
public long getId()
{
return this.id;
}
public void setId(long id)
{
this.id = id;
}
public String getCity()
{
return this.city;
}
public void setCity(String city)
{
this.city = city;
}
public String getCountry()
{
return this.country;
}
public void setCountry(String country)
{
this.country = country;
}
public String getCounty()
{
return this.county;
}
public void setCounty(String county)
{
this.county = county;
}
public String getEmail()
{
return this.email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getFirstname()
{
return this.firstname;
}
public void setFirstname(String firstname)
{
this.firstname = firstname;
}
public BigInteger getHomePHONENUM()
{
return this.homePHONENUM;
}
public void setHomePHONENUM(BigInteger homePHONENUM)
{
this.homePHONENUM = homePHONENUM;
}
public BigInteger getMobilePHONENUM()
{
return this.mobilePHONENUM;
}
public void setMobilePHONENUM(BigInteger mobilePHONENUM)
{
this.mobilePHONENUM = mobilePHONENUM;
}
public String getPostcode()
{
return this.postcode;
}
public void setPostcode(String postcode)
{
this.postcode = postcode;
}
public String getPropertynum()
{
return this.propertynum;
}
public void setPropertynum(String propertynum)
{
this.propertynum = propertynum;
}
public String getSecondname()
{
return this.secondname;
}
public void setSecondname(String secondname)
{
this.secondname = secondname;
}
public String getStreetname()
{
return this.streetname;
}
public void setStreetname(String streetname)
{
this.streetname = streetname;
}
public BigInteger getWorkPHONENUM()
{
return this.workPHONENUM;
}
public void setWorkPHONENUM(BigInteger workPHONENUM)
{
this.workPHONENUM = workPHONENUM;
}
}
Take a look at GeneratedValue's strategy. It typically looks something like:
#GeneratedValue(strategy=GenerationType.IDENTITY)
you must be using update in your hbm2ddl property. make the changes and update it to Create so that it can create the table.
<property name="hbm2ddl.auto">create</property>
It worked for me.
Dropping the table from the database manually and then re-running the application worked for me. In my case table was not created properly(with constraints) I guess.
I had this issue. My mistake was i had set the insertable and updatable fileds as false and was trying to set the field in the request. This field is set as NON NULL in DB.
#ManyToOne
#JoinColumn(name="roles_id", referencedColumnName = "id", insertable = false, updatable = false, nullable=false)
#JsonBackReference
private Role role;
Later I changed it to - insertable = true, updatable = true
#ManyToOne
#JoinColumn(name="roles_id", referencedColumnName = "id", insertable = true, updatable = true, nullable=false)
#JsonBackReference
//#JsonIgnore
private Role role;
It worked perfectly later.
I came here because of the error message, turns out I had two tables with the same name.
I had the same problem. I found the tutorial Hibernate One-To-One Mapping Example using Foreign key Annotation and followed it step by step like below:
Create database table with this script:
create table ADDRESS (
id INT(11) NOT NULL AUTO_INCREMENT,
street VARCHAR(250) NOT NULL,
city VARCHAR(100) NOT NULL,
country VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
create table STUDENT (
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
entering_date DATE NOT NULL,
nationality TEXT NOT NULL,
code VARCHAR(30) NOT NULL,
address_id INT(11) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT student_address FOREIGN KEY (address_id) REFERENCES ADDRESS (id)
);
Here is the entities with the above tables
#Entity
#Table(name = "STUDENT")
public class Student implements Serializable {
private static final long serialVersionUID = 6832006422622219737L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
}
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id #GeneratedValue
#Column(name = "ID")
private long id;
}
The problem was resolved.
Notice: The primary key must be set to AUTO_INCREMENT
Another suggestion is to check that you use a valid type for the auto-generated field. Remember that it doesn't work with String, but it works with Long:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public Long id;
#Constraints.Required
public String contents;
The above syntax worked for generating tables in MySQL using Hibernate as a JPA 2.0 provider.
Just add not-null constraint
I had the same problem. I just added not-null constraint in xml mapping. It worked
<set name="phone" cascade="all" lazy="false" >
<key column="id" not-null="true" />
<one-to-many class="com.practice.phone"/>
</set>
Maybe that is the problem with the table schema. drop the table and rerun the application.
In addition to what is mentioned above, do not forget while creating sql table to make the AUTO INCREMENT as in this example
CREATE TABLE MY_SQL_TABLE (
USER_ID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
FNAME VARCHAR(50) NOT NULL,
LNAME VARCHAR(20) NOT NULL,
EMAIL VARCHAR(50) NOT NULL
);
When your field is not nullable it requires a default value to be specified on table creation. Recreate a table with AUTO_INCREMENT properly initialized so DB will not require default value since it will generate it by itself and never put NULL there.
CREATE TABLE Persons (
Personid int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (Personid)
);
https://www.w3schools.com/sql/sql_autoincrement.asp
I solved it changuing #GeneratedValue(strategy = GenerationType.IDENTITY) by #GeneratedValue(strategy = GenerationType.AUTO)
By the way i didn't need to put it to create, just:
spring.jpa.hibernate.ddl-auto: update
Please check whether the Default value for the column id in particular table.if not make it as default
I had the same problem. I was using a join table and all I had with a row id field and two foreign keys. I don't know the exact caused but I did the following
Upgraded MySQL to community 5.5.13
Rename the class and table
Make sure I had hashcode and equals methods
#Entity
#Table(name = "USERGROUP")
public class UserGroupBean implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "USERGROUP_ID")
private Long usergroup_id;
#Column(name = "USER_ID")
private Long user_id;
#Column(name = "GROUP_ID")
private Long group_id;
The same exception was thrown if a DB table had an old unremoved column.
For example:
attribute_id NOT NULL BIGINT(20), and attributeId NOT NULL BIGINT(20),
After removing the not used attribute, in my case contractId, the problem was resolved.
This happened to me with a #ManyToMany relationship. I had annotated one of the fields in the relationship with #JoinTable, I removed that and used the mappedBy attribute on #ManyToMany instead.
I tried the code and in my case the code below solve the issue. I had not settled the schema properly
#Entity
#Table(name="table"
,catalog="databasename"
)
Please try to add ,catalog="databasename" the same as I did.
,catalog="databasename"
In my case,
I altered that offending tables and the field "id" in question I made it AUTO_INCREMENT, I still need to figure out why on deployment time it was not making it "AUTO_INCREMENT" so that I have to do it by myself!
What about this:
<set name="fieldName" cascade="all">
<key column="id" not-null="true" />
<one-to-many class="com.yourClass"/>
</set>
I hope it helps you.
Try to change Long object type to long primitive type (if using primitives is ok for you).
I had the same problem and changing type helped me.
I had this issue, by mistake I had placed #Transient annotation above that particular attribute. In my case this error make sense.
"Field 'id' doesn't have a default value" because you didn't declare GenerationType.IDENTITY in GeneratedValue Annotation.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
This issue is because sometimes you need to again update/create the database or sometimes if you have added the field in db table but not not entity class then it can not insert any null value or zero so this error came.
So check both side.Db and Entity class.
i have got such error in GCP cloud sql when model field didn't match correct table field in db.
Example:
when in model field is fieldName
table in db should have field field_name
Fixing table field name helped me.
I solved similar problem, when I altered the database column type , and did not add auto_increment. After adding back auto_increment in the alter table command (as in my original table creation) it worked
In my case I have not added the below property in my application.properties file:
spring.jpa.database-platform = org.hibernate.dialect.MySQL5InnoDBDialect
And added the following annotation to my entity class's Id column:
#GeneratedValue(strategy = GenerationType.IDENTITY)
And after adding this I have also drop my table manually from datatbase and run my project again that creates a new table with all default constraints for the table.
To delete just delete your schema is a really bad suggestion. There is a problem and it's best to find and fix it.
In my case I was using Envers this creates an Audit table for when entries are updated. But this audit table does not get updated itself it seems when the schema updates (At least not ID and it's relationships)
I just eddited the audit tables offending property and done. Everything back to normal.
To find what the issue is turn the following properties on in application.properties file
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
This will show you what SQL it is trying to executing and hopefully it will provide clarity on real issue.
Add a method hashCode() to your Entity Bean Class and retry it