Spring data JPA doesn't delete entity - java

I have a problem with deleting entity from database. Whatever I do anyway it doesn't delete.
Driver class
#Entity
#Table(name = "drivers")
public class Driver {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "driver", fetch = FetchType.EAGER)
#JsonSerialize(using = RatingsSerializer.class)
private List<Rating> ratings;
// other fields. Getters and Setters...
}
Rating class
#Entity
#Table(name = "ratings")
#JsonDeserialize(using = RatingDeserializer.class)
public class Rating {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "driver_id")
private Driver driver;
#ManyToOne
#JoinColumn(name = "client_id")
private Client client;
private int mark;
private Date createdAt;
//Getters and Setters ...
}
First one what I do is annotate ratings with #OneToMany(mappedBy = "driver", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.REMOVE) and when call driverRepository.delete(driver) it throws:
org.postgresql.util.PSQLException: ERROR: update or delete on table "drivers" violates foreign key constraint "fk3raf3d9ucm571r485t8e7ew83" on table "ratings"
Ok, choose another way. Try to delete each rating object using ratingRepository, but never happens, it just iterate thorough each rating item and throw again error
org.postgresql.util.PSQLException
Next step was to set for each rating item Client and Driver to null. Now driver entity is deleted from database but rating entity remain in database.
What happens?
Spring Data JPA version: 1.5.7

It looks that your Foreign Key error is related to Client table which is linked according to your code line:
#ManyToOne
#JoinColumn(name = "client_id")
private Client client;
So, if you add cascade = CascadeType.REMOVE within the annotation, it may works. But, that' up to you if you want to delete everything on cascade including Client row. If not, then update that column value first to null.

Related

Hibernate remove just the relation, not the entity on the relation

I have a one to many relation on post class, and on the relation table I have one to one relation with user. Everything works find, but i want to be able to remove the relation, keeping the user entity, is that possible?
At this moment with the annotation orphanRemoval = true when I remove from post Detail list an element, this its removed from post_details table but the user is removed too.
#Entity
#Table(name = "ta_post")
public class Post{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private Date fcDate;
#OneToMany(mappedBy="post", cascade=CascadeType.ALL, orphanRemoval = true)
private List<PostDetails>;
}
#Entity
#Table(name = "ta_user")
public class User{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int mail;
}
#Entity
#Table(name = "ta_post_details")
public class PostDetails{
private int id;
#ManyToOne
#JoinColumn(name="post_id")
private Post post;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="user_id")
private User user;
private String postComments;
}
You must remove the CascadeType.ALL from the PostDetails. If you want to be able to change the User through the PostDetails, you can set the CascadeType to PERSIST or MERGE. If you want to create a PostDetail along with an User, you need to include the CascadeType CREATE.
I'd guess you are creating the user somewhere else and you just associate one with a Post, so removing the CascadeType.ALL should be enough to not delete your User from the database.

JPA many to one relation

I have a question regarding ManyToOne relationship.
Assume I have 2 beans:
#Entity
#Table(name = "accounts")
public class Account {
#Id
#Column(name = "account_id")
private int account_id;
}
#Entity
#Table(name = "broker_account")
public class BrokerAccount {
#Id
#Column(name = "broker_account_id")
private int broker_account_id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="account_id", referencedColumnName = "account_id")
private Account account;
}
I am querying the entity below (plain get all query)
entityManager.createQuery("from BrokerAccount", BrokerAccount.class)
I thought that if I query BrokerAccount entity the account_id column will be populated by default on the Account object, since it exists in the BrokerAccount table as well, however all the Account fields are empty.
Am I missing something, should I define this field/column on the BrokerAccount entity itself as well to get its value?
You have defined the Account association as #ManyToOne(fetch = FetchType.LAZY). This means that while performing the entityManager.createQuery("from BrokerAccount", BrokerAccount.class), there will be no join on the Account and its data will not be fetched at that time.
In order to make the persistence provider fetch the Account data you would need to interact with the reference while being in the same transactional method, f.e.: brokerAccount.getAccount().getAccountId();
If you want to simply have a repeated column for the fk you can do:
#Column(name = "account_id", insertable=false, updatable=false)
private int account_id;

Cannot add or update a child row: a foreign key constraint fails - One-To-Many relationship - Hibernate

I am working with one-to-many relation using hibernate.
profesor.java
#Entity
public class Profesor {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
#ManyToMany(mappedBy = "profesors", fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
private List<Classes> classes;
#OneToMany(mappedBy="profesor", fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
#Fetch(value = FetchMode.SUBSELECT)
private List<Post> post;
}
My professor table is already in relation with classes table as many-to-many. Now I am trying to connect it with post table as one-to-many.
My post model looks like this:
post.java
#Entity
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
private long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn (name="profesor_id",referencedColumnName="id",nullable=false,unique=true)
private Profesor profesor;
}
Here is how my table post looks in database.
I am getting following error:
Cannot add or update a child row: a foreign key constraint fails (`database`.`#sql-45e3_695`, CONSTRAINT `FKfkqyncksuk5vuw09wam4sryyd` FOREIGN KEY (`profesor_id`) REFERENCES `profesor` (`id`))
What am I doing wrong?
SOLUTION:
First I created post table without profesor_id. I added profesor_id when I started to create relationship between tables and then profesor_id was set to null. When I cleared my table I could run my application normally.
its clear you are violating some constraint, i would say you are trying to remove a proffesor which is already linked to post, try to remove nullable = false
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn (name="profesor_id",referencedColumnName="id",unique=true)
private Profesor profesor;

How to manage OnetoOne inserting data in child only

I am very new to hibernate and I am working with JPA and Hibernate4. Trying to insert parent object in child as onetoone relationship.
I went through some tutorials but All the example in the web shows, inserting both parent and child tables.
I want to insert data in child table only.
I have two tables called user and department.
User table consists of user details with department as onetoone relationship, as follows,
#Entity
#Table(name = "User")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "_id")
private String id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "departmentId")
private Department departmentId;
// getters and setters...
}
Below is my Department entity,
#Entity
#Table(name = "Department")
public class Department {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "_id")
private String id;
#Column(name = "name")
private String name;
// getters and setters...
}
In department table there is only 4 data. I want to insert data only in user data while insert into it and don't want to insert in Department.
How can I do that.Please assist.
You have to use mappedBy for this, as mentoned below in child Table, Department in your case
#OneToOne(mappedBy="department")
private UserEntity user;
These posts explain you better this,
JPA JoinColumn vs mappedBy
Understanding mappedBy annotation in Hibernate
You need to specify the relationship owner using mappedBy property in the OneToOne mapping in the owner side, here in your case in the Department class, you should add:
#OneToOne(mappedBy="department")
private UserEntity user;
I updated your code, to included the stated annotation and also renamed the Department property in your UserEntity class from departmentId to department to avoid confusion between relationship owner and its id:
#Entity
#Table(name = "User")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "_id")
private String id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "departmentId")
private Department department;
// getters and setters...
}
Below is the Department entity,
#Entity
#Table(name = "Department")
public class Department {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "_id")
private String id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy="department")
private UserEntity user;
// getters and setters...
}
This will give you the right mapping with the expected behaviour.
In the #OneToOne annotation, the default value for parameter optional is true. So your annotation is the same as #OneToOne(fetch = FetchType.EAGER, optional = true). This means you can simply leave the Department in a UserEntity instance empty. In that case, persisting it results in persisting only a user entity and no department.
Even if you created a Department instance and assigned it to a UserEntity instance, persisting the UserEntity would not automatically persist the Department, since you don't have any cascade parameter in your annotation. If you don't automatically cascade persists, you would have to persist the Department first and then persist the corresponding user entity.
Maybe you're asking about using existing departments for your user entities. In that case, you first need to get the department via Hibernate (or the JPA API) from an entity manager. The entity instance you get is managed by Hibernate, and you can then set it in a UserEntity and persist that, to have it refer to the department.
Finally, I think one department will probably have more than one user. It might make more sense to have a #ManyToOne annotation instead of #OneToOne, indicating multiple users can refer to the same department, but that depends on your domain model.

JPA Unknown Column in Field List

I have a relation between Accommodation and Booking classes, and also I set a foreign key in booking table.
ALTER TABLE `project`.`booking`
ADD INDEX `fk_accId_fk_idx` (`accommodation` ASC);
ALTER TABLE `project`.`booking`
ADD CONSTRAINT `fk_accId_fk`
FOREIGN KEY (`accommodation`)
REFERENCES `project`.`accommodation` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
Accommodation class:
#Entity
....
public class Accommodation implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private BigInteger id;
#OneToMany(mappedBy = "accommodation", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
#JsonManagedReference
private List < Booking > bookings;
......getters setters
}
Booking class:
#Entity
public class Booking implements Serializable {
......
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "bookings", nullable = true)
#JsonBackReference
private Accommodation accommodation;
....getters setters
}
When I execute a query for listing accommodations, I get unknown column in field list error.
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'bookings7_.bookings' in 'field list'
Even I set the relation and define the foreign key in table, what is the reason that I get this error?
Try to define your join-table mapping manually in JPA. Drop your schema and let JPA create your tables:
Accommodation class
#OneToMany(mappedBy = "accommodation", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
#JsonManagedReference
private List < Booking > bookings;
Booking class
#ManyToOne(fetch = FetchType.EAGER)
#JoinTable(name = "accommodation_booking_join_table",
joinColumns = {#JoinColumn(name="booking_id")},
inverseJoinColumns = #JoinColumn(name = "accommodation_id"))
#JsonBackReference
private Accommodation accommodation;
Try changing your column names to lower case in your db and entity class.
I had a situation like that, and I solved it by changing the field's position on the query. Looks like it's a MySQL bug, like (or the same as) the one mentioned on this post:
https://bugs.mysql.com/bug.php?id=1689
The description of this MySQL bug mentioned a similar workaround solution: "I found that by swapping that field's position in the table with another field that it worked OK."

Categories