EclipseLink Remove Cascade - eclipselink

I have been developing a web application running on the Glassfish Server. I use JPA with EclipseLink implementation.
These are my two entity classes. I represent the relation between them below. When I start the Glassfish server and delete the lesson entity, Cascade works. It deletes all of the Test entities of it. Then I add lesson entity and test entity related to it. But when I try to delete the Lesson entity, at this time Cascade does not work and throws "foreign key constraint" error. After Server restarting, Cascade again works. ??? What is the difference? Why do Cascade operation only work at the startup?
Thank you.
#Entity
public class Lesson implements Serializable {
...
#OneToMany( fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.REMOVE }, mappedBy = "lesson" )
private List< Test > tests;
...
}
#Entity
public class Test implements Serializable {
...
#ManyToOne( targetEntity = Lesson.class, fetch = FetchType.LAZY )
#JoinColumn( name = "lessonNo", insertable = true, updatable = true, nullable = false )
private Lesson lesson;
...
}

Related

Optaplanner: problems with InverseRelationShadowVariable

have a many-1 relationship pupil-formGroup: pupils are assigned to a formGroup and a formGroup can contain many pupils. I have attempted to implement an InverseRelationShadowVariable having watched your video/tutorial https://www.youtube.com/watch?v=ENKHGBMDaCM (which does not quite correspond with the latest optaplanner documentation I realise)
FormGroup extracts
#Entity
#PlanningEntity
public class FormGroup {
#InverseRelationShadowVariable(sourceVariableName = "formGroup")
#OneToMany(mappedBy = "formGroup", fetch = FetchType.EAGER)
private List<Pupil> pupilList = new ArrayList<Pupil>();
public List<Pupil> getPupilList() {
return pupilList;
}
public Integer getPupilCount() {
return pupilList.size();
}
Pupil extracts
#Entity
#PlanningEntity
public class Pupil
#PlanningVariable(valueRangeProviderRefs = "formGroupRange")
#ManyToOne
private FormGroup formGroup;
Config extracts
<solutionClass>org.acme.optaplanner.domain.Plan</solutionClass>
<entityClass>org.acme.optaplanner.domain.Pupil</entityClass>
<entityClass>org.acme.optaplanner.domain.FormGroup</entityClass>
I believe I've followed the steps in the videoexactly (don't we all say that) but at solve time I get hundreds of errors... Repetitions of the following
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
Any hint gratefully received...
The InverseRelationShadowVariable creates a bi-directional relationship between the genuine planning entity (Pupil) and the planning value (FormGroup). This may become problematic if you re-use your planning domain classes for other purposes, such as ORM persistence or serialization.
In this case, Jackson is unable to serialize Pupil, because it references a FormGroup, which has a List containing a reference back to that Pupil. See? An endless loop.
Solve this issue by adding the #JsonIgnore annotation on top of your inverse relation property and breaking that loop for Jackson:
#Entity
#PlanningEntity
public class FormGroup {
#JsonIgnore // THIS IS THE FIX
#InverseRelationShadowVariable(sourceVariableName = "formGroup")
#OneToMany(mappedBy = "formGroup", fetch = FetchType.EAGER)
private List<Pupil> pupilList = new ArrayList<Pupil>();
public List<Pupil> getPupilList() {
return pupilList;
}
public Integer getPupilCount() {
return pupilList.size();
}
...

JPA: single table inheritance possible performance tradeoff

I have following MS SQL DB tables, where I am storing school related data:
HighSchools<---GradeLevels<---Courses<---CourseGrades
The relations between the tables looks like
#Entity
#Table(name = "GradeLevels", schema = "dbo")
public class HighSchoolGradeLevel {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "AttendedId", nullable = false)
private HighSchoolAttended highSchoolAttended;
#OneToMany(mappedBy = "highSchoolGradeLevel")
#OrderBy("createdDate ASC")
private List<HighSchoolCourse> highSchoolCourses = new ArrayList<>(0);
// other fields and getter/setter methods....
}
#Entity
#Table(name = "Courses", schema = "dbo")
public class HighSchoolCourse {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GradeLevelId", nullable = false)
private HighSchoolGradeLevel highSchoolGradeLevel;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "highSchoolCourse", cascade={CascadeType.REMOVE, CascadeType.PERSIST})
#OrderBy("createdDate ASC")
private List<HighSchoolCourseGrade> highSchoolCourseGrades = new ArrayList<>(0);
// other fields and getter/setter methods....
}
#Entity
#Table(name = "CourseGrades", schema = "dbo")
public class HighSchoolCourseGrade {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "CourseId", nullable = false)
private HighSchoolCourse highSchoolCourse;
// other fields and getter/setter methods....
}
The java web-app users can do CRUD operations with the tables data.
The new requirement is to consume the data with the same structure from a third party. The consumed data SHOULD NOT be displayed for the web-app users.
Therefore, I am thinking to use JPA single table inheritance which allows me to:
avoid adding clones of the existing tables
avoid cloning existing business logic which is tight to existing
entity types
avoid code refactoring of existing CRUD ops in case implementing own discriminator column.
The Single table inheritance looks reasonable to use in my, but there is one thing I am not sure about "What is the performance trade off of using Single Table Inheritance, especially while operating on the Parent and its Childs entities?". The question may sound dummy, knowing the fact that Hibernate will update SQL queries with corresponding discriminator statements. But still it would be nice to improve the current knowledge and be sure that the existing users of wep-app will not get bad usage experience.
The existing web-app DAO layer uses with Spring Data JPA. Currently, each of existing tables contains more than ~500k records.

Hibernate: Problem with cascade delete for one to many relation

I have following entity model.
#Entity
#Table(name="product")
public class ProductEntity {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
...
#OneToMany(mappedBy = "productEntity", cascade = CascadeType.ALL)
private List<ProductAddonEntity> productAddonEntities;
}
#Entity
#Table(name="product_addon")
public class ProductAddonEntity {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
...
#ManyToOne()
#JoinColumn(name = "addon_id")
private ProductEntity addonEntity;
}
I want to delete product, and that deletion should also delete all ProductAddon entities, connected with this product. So I declare one to many relation with all cascade types.
But when I try to delete some product, at the beginning Hibernate tries to set null addon_id in product_addon table. But this column have non-null constraint, so deletion fails.
So I added to annotation #ManyToOne parameters
#JoinColumn(name = "addon_id", nullable = false, updatable = false)
But now hibernate just tries to delete product, before deleting product_addon entities, connected with this product. And this deletion fails because of foreign key constraint (Cannot delete or update a parent row: a foreign key constraint fails).
What can be a problem here? This application also uses liquibase, so foreign keys generated not by hibernate. For example, foreign key for addon_id doesn't have actions on delete, but I'm thinking that hibernate does not need these actions, because it works on higher data layer
Orphan removal is aggressive remove cascading mode to remove child object whenever the parent object needs to be deleted(#OneToOne and #OneToMany relationships).
This feature added from JPA 2.0 version.JPA deletion operation
The difference between the two settings is in the response to disconnecting a relationship. For example, such as when setting the address field to null or to another Address object.
#Entity
class Employee {
#OneToOne(cascade=CascadeType.REMOVE)
private Address address;
}
If only cascade=CascadeType.REMOVE is specified no automatic action is taken since disconnecting a relationship is not a remove operation.
#Entity
class Employee {
#OneToOne(orphanRemoval=true)
private Address address;
}
If orphanRemoval=true is specified the disconnected Address instance is automatically removed. This is useful for cleaning up dependent objects (e.g. Address) that should not exist without a reference from an owner object (e.g. Employee).

Attempting achieve low coupling between JPA entities

One issue I'm running into is a good way to map One-To-Many relationships with JPA / Hibernate, without sacrificing SOLID principles along the way. Here's an example of this problem from a current project I'm working on:
Given the following code which defines a unidirectional One-To-Many relationship:
#Entity
#Table(name = "users")
public class User extends AggregateEntity<User> implements HasRoles, HasContactInfo, HasContacts, HasDeals {
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
#JoinColumn(name = "fk_hasContacts")
private Set<Contact> contacts;}
My understanding is that this creates an "fk_hasContacts" column in the "contacts" table, without the "Contact" class knowing or caring which object it is being referenced from. Also, notice how "User" implements the "hasContacts" interface, which creates a decoupling effect between the two entities. If tomorrow I want to add another class; say "BusinessEntity" which also has contacts, there's nothing that needs to be changed within the current code. However, after reading up on the topic in seems that this approach is inefficient from a database performance perspective.
The best way to map a #OneToMany association is to rely on the #ManyToOne side to propagate all entity state changes - As expounded upon here.
Seems to be the prevailing wisdom. Were I to engineer it that way, the "User" class would now look like this:
#Entity
#Table(name = "users")
public class User extends AggregateEntity<User> implements HasRoles, HasContactInfo, HasContacts, HasDeals {
#OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Contact> contacts;
And the (previously decoupled) "Contact" class would now have to look like this:
#Entity
#Table(name = "contacts")
public class Contact extends StandardEntity<Contact> {
#ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "fk_user")
private User user;
The key problem is that it seems from here that JPA doesn't support defining an interface as an entity attribute . So this code:
#Entity
#Table(name = "contacts")
public class Contact extends StandardEntity<Contact> {
#ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "fk_user")
private HasContacts hasContacts;//some class which implements the "HasUser" interface
Isn't an option. Seems one would have to chose between SOLID OOP, and valid ORM entities. After a lot of reading I still don't know whether the hit to database performance is bad enough to justify writing what amounts to tightly coupled, rigid and ultimately bad code.
Are there any workarounds / solutions to this seeming contradiction in design principles?

Hibernate inheritance without table for basic entity

I've never used inheritance in hibernate and I don't know which strategy should I use (or even do I really need to use strategy). I have three tables with the same interface (the same columns) and I want to create three entities with basic interface for them so it will look like this:
#Entity
+ Basic
+ #Entity
#Table(name="TABLE_1")
Table1
+ #Entity
#Table(name="TABLE_2")
Table2
+ #Entity
#Table(name="TABLE_3")
Table3
As you see I don't want to use table for basic entity. If it is possible to do this kind of inheritance, how to do it? Maybe I don't need 'hibernate' inheritance and I should use normal inheritance?
In application it is used like this:
Somewhere in configuration we store information which entity to use (Table1, Table12 or Table3)
Choosen entity is used in our queries (some writen in HQL, some in Criteria) so each query should know which entity to use.
EDIT
What's more each entity can be used as attribute of some entities and we wan't to know which table should be used. For example:
#Entity
#Table(name="USER")
class User {
#Id
private Integer id;
#ManyToOne
#JoinColumn(name = "SOME_ID", referencedColumnName = "ID", nullable = false)
private Basic basicEntity; // how to use proper strategy using some configuration value (eg. class static attribute or configuration value stored in db?)
}
I think this is recommended way of achieving your goal:
#MappedSuperclass
public abstract class BaseEntity {
public static final int SHARED_PAREMETER = 2;
#Column(name = "modified", columnDefinition = "TIMESTAMP DEFAULT NOW()")
protected Date modified;
//... other fields, getters and setters
}
#Entity
#Table(name = "TABLE_1")
public class Table1 {
#Id
private Integer id;
#ManyToOne
#JoinColumn(name = "SOME_ID", referencedColumnName = "ID", nullable = false)
private Table2 table2;
}
#Entity
#Table(name = "TABLE_2")
public class Table2 {
#Id
private Integer id;
}
In this case, we will have only two tables but both would have fields from BaseEntity. You can't, though, make a relation in Entity to an abstract class but in processing you're fully entitled to do something like this:
public void process(BaseEntity entity){
// processing..
}