Hibernate created an automatic breaking constraint - java

So I have 3 classes, Category, Question and Comment.
Both classes have a OneToMany relationship to Comment.
For some reason Hibernate has decided to put in a constraint on Comment resulting in the following exception:
ERROR: insert or update on table "comment" violates foreign key constraint "fknapu44p12w4v7wreaog7vgc80"
Detail: Key (q_comment)=(03f7ed17-4fa1-48d9-ac17-9842e233fde4) is not present in table "category".
Both Question and Category have to following bit of code:
#OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
#JoinColumn(name = "t_comment")
#LazyCollection(LazyCollectionOption.FALSE)
private List<Comment> comment;
And it seems as if I can correctly save the Category object with a new Comment in the list, but it breaks when I do the same to Question
So does anyone have any idea of what might cause this?
To clarify: the tables where created by hibernate which generated the following sql:
create table category (id varchar(255) not null, color varchar(7), name varchar(255), parent_questionnaire varchar(255), primary key (id))
create table comment (id varchar(255) not null, comment varchar(2048), timestamp int8, sent_by varchar(255), session varchar(255), t_recommendation varchar(255), t_comment varchar(255), primary key (id))
create table question (id varchar(255) not null, question varchar(255), type int4, parent_category varchar(255), primary key (id))
alter table if exists comment add constraint FKnapu44p12w4v7wreaog7vgc80 foreign key (t_comment) references category

Related

[HY000][1215] Cannot add foreign key constraint

application_user
-- auto-generated definition
create table application_user
(
id bigint auto_increment
primary key,
email varchar(255) not null,
is_active bit null,
name varchar(255) not null,
password varchar(255) not null,
surname varchar(255) not null,
username varchar(255) not null
)
engine = MyISAM;
I have a table that generated by hibernate.
I want to create a table and add a foreign key manually.
So far I tried this
application_user_log
CREATE TABLE application_user_log (
log_id BIGINT NOT NULL AUTO_INCREMENT,
fk_user_id BIGINT NOT NULL,
old_user_name BIGINT NOT NULL,
new_user_name BIGINT NOT NULL,
PRIMARY KEY (log_id),
FOREIGN KEY (fk_user_id) REFERENCES application_user(id)
) ;
And I got this error message.: [HY000][1215] Cannot add foreign key constraint
Why I got this error?
Well I don't know why my answer got converted into a comment, but I knonw that MyISAM doesn't support foreign keys. You can read details here.

How to update a foreign key column?

I have below tables:
create table TABLE1 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, deptId int(11) NOT NULL, DeptName varchar(32) NOT NULL, PRIMARY KEY (id), KEY Dept (deptId, DeptName))
create table TABLE2 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, empId int(11) NOT NULL, DeptName varchar(32) NOT NULL, PRIMARY KEY (id), KEY DeptName (DeptName), CONSTRAINT T2FK FOREIGN KEY (DeptName) REFERENCES TABLE1 (DeptName))
TABLE1 has a MUL key defined with both dept id and dept name.
TABLE2 has a Foreign key which references only Dept name from TABLE1
The DTO for TABLE2 gets created like below:
#org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.IGNORE)
#javax.persistence.ManyToOne(targetEntity = org.amru.persistence.dto.TABLE1DTOImpl.class, fetch=javax.persistence.FetchType.EAGER)
#javax.persistence.JoinColumn(name = "deptName")
public org.amru.persistence.dto.TABLE1DTO getTABLE1() {
return TABLE1;
}
When I try to insert a row in TABLE2, it fails with foreign key constraint violation exception.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`amru`.`TABLE2`, CONSTRAINT `T2FK` FOREIGN KEY (`DeptName`) REFERENCES `TABLE1` (`DeptName`))
I also see a EntityExistsException when I debug
What is possibly wrong? Is it recommended to refer a part of MUL key as foreign key in another table?
I am using jpa, hibernate, jboss, ejb and mysql
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails
What is possibly wrong?
This is very clear that, DeptName is foreign key in TABLE2, which is referring from TABLE1. So, you are not allowed to change the value in parent table as the data is being referenced in other table.
If you are supposed to do this, then you need to alter your table to apply cascade changes to child table as well for your Foreign Key
FOREIGN KEY (DeptName) REFERENCES TABLE1 (DeptName) ON DELETE CASCADE ON UPDATE CASCADE

Hibernate cannot rebuild tables due to broken foreign keys

Alright so, I have a Spring Boot application (1.5.2.RELEASE) that uses Hibernate (5.0.12.Final) and I'm having a few problems with Hibernate being unable to properly re-create my database on startup.
I configured Hibernate to create the tables again on startup:
spring.jpa.hibernate.ddl-auto=create
Here is my first entity (Client):
#Entity
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
private String name;
#NotNull
private String firstName;
#Email
#NotNull
private String email;
#Valid
#Embedded
private Credentials credentials = new Credentials();
#OneToMany(mappedBy = "client")
private List<Reservation> reservations = new ArrayList<>();
//Getters, Setters, hashcode & equals omitted
}
Reservation entity:
#Entity
public class Reservation {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
private Client client;
#Enumerated(EnumType.STRING)
private State state = State.UNTREATED;
//Getters, Setters, hashcode & equals omitted
}
Here's an overview of the created database:
Here's the console output, I tried to abbreviate it for simplicity's sake:
INFO : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
INFO : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
INFO : HHH000227: Running hbm2ddl schema export
Hibernate: alter table reservation drop foreign key FKoewar6f18rkn4iptr6da4oysv
ERROR : HHH000389: Unsuccessful: alter table reservation drop foreign key FKoewar6f18rkn4iptr6da4oysv
ERROR : Can't DROP 'FKoewar6f18rkn4iptr6da4oysv'; check that column/key exists
Hibernate: drop table if exists client
ERROR : HHH000389: Unsuccessful: drop table if exists client
ERROR : Cannot delete or update a parent row: a foreign key constraint fails
Hibernate: drop table if exists reservation
Hibernate: drop table if exists restaurant
Hibernate: create table client (id bigint not null auto_increment, created_on datetime, credentials_version integer not null, hash varchar(255), username varchar(255), email varchar(255) not null, first_name varchar(255) not null, name varchar(255) not null, primary key (id))
ERROR : HHH000389: Unsuccessful: create table client (id bigint not null auto_increment, created_on datetime, credentials_version integer not null, hash varchar(255), username varchar(255), email varchar(255) not null, first_name varchar(255) not null, name varchar(255) not null, primary key (id))
ERROR : Table 'client' already exists
Hibernate: create table reservation (id bigint not null auto_increment, state varchar(255), client_id bigint, primary key (id))
Hibernate: create table restaurant (id bigint not null auto_increment, primary key (id))
Hibernate: alter table reservation add constraint FKoewar6f18rkn4iptr6da4oysv foreign key (client_id) references client (id)
INFO : HHH000230: Schema export complete
INFO : Initialized JPA EntityManagerFactory for persistence unit 'default'
INFO : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
INFO : HHH000227: Running hbm2ddl schema export
ERROR : HHH000389: Unsuccessful: alter table `Reservation` drop foreign key `FK8gjvlt7rp8i9kp7rdmn107ni7`
ERROR : Can't DROP 'FK8gjvlt7rp8i9kp7rdmn107ni7'; check that column/key exists
ERROR : HHH000389: Unsuccessful: drop table if exists `Client`
ERROR : Cannot delete or update a parent row: a foreign key constraint fails
ERROR : HHH000389: Unsuccessful: create table `Client` (`id` bigint not null auto_increment, `createdOn` datetime, `credentialsVersion` integer not null, `hash` varchar(255), `username` varchar(255), `email` varchar(255) not null, `firstName` varchar(255) not null, `name` varchar(255) not null, primary key (`id`))
ERROR : Table 'client' already exists
INFO : HHH000230: Schema export complete
I don't know if it matters but the MySQL database version is 5.7.13 running on Windows. Also I didn't include the Restaurant entity and the Credentials embeddable.
I find it strange that Hibernate is trying to drop a foreign key that doesn't exist first and then drop the right one and both fail (if I'm reading it correctly).
What is the reasoning/cause behind this? And how to prevent these issues?
I've looked at other relevant SO questions and they are usually caused by invalid names or simmilar but I don't see anything wrong with my naming. I've also tried prefixing all my tables with "tbl_" and renaming some columns with a prefix as well just in case something was causing a conflict but no luck.
It's bothering me because the database is not updating properly and during active development I don't want to drop/create schema manually every time. Maybe it's worth mentioning that, even if the schema is empty, on startup, hibernate will give errors that things don't exist.
Try it. I think issue in Reservation
#ManyToOne
#JoinColumn(name = "client_id")
private Client client;
Firstly, you should understand how foreign key constraint names are generated:
How does hibernate generate foreign key constraint names?
So, if you change table or foreign key column names, you will have a different foreign key constraint name and Hibernate will not be able to delete the old foreign key constraint.
What you can do:
Specify a foreign constraint name using
#javax.persistence.ForeignKey annotation (don't confuse it with
#org.hibernate.annotations.ForeignKey, although it can be used
to).
Use spring.jpa.hibernate.ddl-auto = update to just update schema,
not to recreate it every time.
Use a naming strategy to generate foreign key names (working with Hibernate 5 only). But you will need to think how to combine table, associated table, columns names to have not often foreign constraint name change: Need help in implementing ImplicitNamingStrategy for foreign key column names in Hibernate 5

I get this error "Error code 30000, SQL state 42X01: Syntax error: Encountered "AUTO_INCREMENT" at line 3, column 22." when I create a sql table

CREATE TABLE Products
(
Item_ID int NOT NULL AUTO_INCREMENT,
item_make varchar(255) NOT NULL,
item_model varchar(255),
brought_in_date varchar(255),
collected_date varchar(255),
whats_wrong varchar(255),
what_was_done varchar(255),
Price varchar(255),
CID varchar(255),
PRIMARY KEY (Item_ID),
FOREIGN KEY (CID) REFERENCES Customers(CID)
)
When I execute this I get this error
Error code 30000, SQL state 42X01: Syntax error: Encountered "AUTO_INCREMENT" at line 3, column 22.
I am using sql on the java database, derby
Does anyone know what I did wrong.
Instead of AUTO_INCREMENT (which is MySQL dialect), you should use the SQL standard GENERATED ALWAYS AS IDENTITY as supported by Derby:
CREATE TABLE Products
(
Item_ID int GENERATED ALWAYS AS IDENTITY not null primary key,
item_make varchar(255) NOT NULL,
item_model varchar(255),
brought_in_date varchar(255),
collected_date varchar(255),
whats_wrong varchar(255),
what_was_done varchar(255),
Price varchar(255),
CID varchar(255),
FOREIGN KEY (CID) REFERENCES Customers(CID)
)
Accordign to the Derby definition table page the syntax would be something like this:
CREATE TABLE PRODUCTS
(
ITEM_ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1)
...
UNIQUE (MAP_ID)
)
Link here derby docs

Mapping Linking Table with 3 PK's in Hibernate

right now I'm having trouble mapping a linking table with Hibernate.
First of all I want to explain what I want to map:
I have 3 tables: Product , DocumentType, Language.
One Product can have each DocumentType (at the moment we have 7 DocumentTypes) in each specific Language (at the moment we have 3 Languages)
That means product "1" can have DocumentType "A" in language "EN", "ES" and "FR".
I created a linking table with 3 foreign keys which are also composite primary key.
Here is how my sql looks like.
CREATE TABLE Person(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(255)
);
CREATE TABLE DocumentType(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(255),
key varchar(255)
);
CREATE TABLE Language(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(255),
code varchar(2)
);
CREATE TABLE Person_DocumentType_Language(
person_id int NOT NULL,
doc_id int NOT NULL,
lang_id NOT NULL,
FOREIGN KEY(person_id)
REFERENCES Person(id),
FOREIGN KEY(doc_id)
REFERENCES DocumentType(id),
FOREIGN KEY(lang_id)
REFERENCES Language(id),
PRIMARY KEY(person_id, doc_id, lang_id)
);
With the last linking table I could tell which Person has which DocumentTypes and in which Languages.
I'm mostly interested in the information which DocumentType has which Language for one Person.
Say I'm Person A. Now I want to know which DocumentTypes I have with which Languages. In SQL it would look like this I think:
Select doc_id, lang_id from Person_DocumentType_Language where person_id=1
Does that make sense? And how could I map this in Hibernate?
One approach is have a Map from DocumentType to Language. I'm a bit rusty on the exact annotation, but here is a start:
public class Person {
#Id
public int id;
#OneToMany(targetEntity=Language.class)
#MapKeyClass(Integer.class)
#CollectionTable(name="Person_DocumentType_Language")
#MapKeyColumn(name="doc_id")
public Map<DocumentType,Language> docTypeLang;
}

Categories

Resources