Jpa OneToMany Relation not woriking - exception

I have an issue trying to persist an Entity with a #OneToMany Relatioship and I don't get it solved. (Sorry, I'm not an english native speaker).
These are the Entities:
#Entity
#Table(name = "PARENT")
#lombok.ToString
#lombok.EqualsAndHashCode(callSuper = false, of = { "id" })
public class Parent extends EntityBase<Long> {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PARENT_SEQ")
#SequenceGenerator(name = "PARENT_SEQ", sequenceName = "PARENT_SEQ")
#Column(name = "PARENT_ID")
private Long id;
#OneToMany(targetEntity = Child.class, cascade = CascadeType.ALL)
#JoinColumns({ #JoinColumn(name = "PARENT_ID") })
private List<Child> children;
}
The Child Entity looks like this:
#Entity
#Table(name = "CHILD")
#lombok.ToString
#lombok.EqualsAndHashCode(callSuper = false, of = { "id" })
public class Child extends EntityBase<Long> {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CHILD_SEQ")
#SequenceGenerator(name = "CHILD_SEQ", sequenceName = "CHILD_SEQ")
#Column(name = "CHILD_ID")
private Long id;
}
The Exception I get is:
integrity constraint violation: NOT NULL check constraint; SYS_CT_10153 table: CHILD column: PARENT_ID
Since Cascade is set to all, I though, the chidren would be persisted and that this occures after Parent has been persisted. That way the PARENT_ID already exists and will be set as the foreign key in the children rows.
The tables look like this:
PARENT
PARENT_ID NUMBER(30,0) No
CHILD
CHILD_ID NUMBER(30,0) No
PARENT_ID NUMBER(30,0) No
Has anybody an Idea what I'm possibly doing wrong? Thanks in advance for any help.

I solved. I forgot to add the other side of the relationship :-/. It means, child.setParent(parent). Sorry for the time waste....

Related

How to bypass MapsId for a single default case

I have created an Employee entity and a corresponding ProfilePicture entity:
#Entity
#Table(name = "employee")
public class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name", nullable = false)
private String firstName;
#Column(name = "last_name", nullable = false)
private String lastName;
}
#Entity
#Table(name = "profile_picture")
public class ProfilePicture {
#Id
private Long id;
#OneToOne
#MapsId
private Employee employee;
#Column(name = "image")
private byte[] image;
}
Now, I want to add a default image to my profile_picture table. I am using a MySQL database and introducing a default image seems to be a problem, since my profile_picture database entries require an association with an employee. The issue is that MapsId is trying to map the id of the associated employee to the id of my profile-picture. When there is no associated employee, this is impossible.
Does anyone have an idea how to solve this problem? I know I could create a dummy employee, but I don't want to do this. I would like to have an entry in my profile_picture table for which the employee_id column is simply null. Right now, however, this is violating some constraints. I know I will have to think of a different solution, I am just asking for ideas.

Getting parent_id for nested children

I'm new to JPA and I'm stumped on how to capture the parent id param for nested children. I have two entities, Data and Property. Right now I successfully managed to create a one to many mapping from Data to Property. The thing is that Property can have its own children of itself. The "first layer" properties are able to get and save the data id value, but properties nested in another property are unable to do so. I was wondering if there is a method to do something like this since I could not find any information on it online.
Data (parent class)
#Entity
#Table(name = "data")
public class Data implements Serializable {
// omitted non relevant code
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(targetEntity = EventProperty.class, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "data_id", referencedColumnName = "id")
private List<EventProperty> properties;
}
Property (child class)
#Entity
#Table(name = "property")
public class Property implements Serializable {
private static final long serialVersionUID = -1100374255977700675L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#ManyToOne
#JoinColumn(name = "data_id", referencedColumnName = "id")
private EventData eventData;
#ManyToOne
#JoinColumn(name = "parent_id", referencedColumnName = "id")
private EventProperty parent;
#OneToMany(targetEntity = EventProperty.class, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "parent_id", referencedColumnName = "id")
private List<EventProperty> children;
}
I'm wondering if storing the properties as a List in Data is the right way to go, or if there's any way to set data_id of a child Property to be the same as the parent Property if it is null, or if there's some other correct way that I am not aware of. Any help would be greatly appreciated!

Jackson JSON infinite recursion without omiting anything from the serialization

I want to serialize and eventually deserialize an object to perform an export/import operation. I use Jackson library because of the extend annotation provided. I do break the infinite recursion by using the latest tags #JsonManagedReference, #JsonBackReference. But the problem here #JsonBackReference does omit the annotated part from the json file so I am not able to set the relationship while importing.
The relationship btwn entities can be shown:
public class A{
#Id
#Column(name = "ID", unique = true, precision = 20)
#SequenceGenerator(name = "a_generator", sequenceName =
"SEQ_A", initialValue = 1, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"a_generator")
private Long id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "metricDefinition",
fetch = FetchType.LAZY, orphanRemoval = true)
#Fetch(FetchMode.SELECT)
#NotAudited
#JsonManagedReference
private Set<B> bSet= new HashSet<B>();
}
public class B{
#Id
#Column(name = "id", unique = true, precision = 20)
#SequenceGenerator(name = "b_generator", sequenceName = "seq_b", initialValue = 1, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b_generator")
private Long id;
#ManyToOne(cascade = {CascadeType.REFRESH})
#JoinColumn(name = "a_id")
#Fetch(FetchMode.SELECT)
#JsonBackReference(value = "a-b")
private A a;
#ManyToOne(cascade = {CascadeType.REFRESH})
#JoinColumn(name = "ref_a_id")
#Fetch(FetchMode.SELECT)
#JsonBackReference(value = "a-ref")
private A refA;
#Column(name = "is_optional")
#Fetch(FetchMode.SELECT)
private boolean isOptional;
#Column(name = "name")
#Fetch(FetchMode.SELECT)
private String name;
When I serialize any A object, it does serialize the B's included but the referenced A and refA are omitted. So, when I import A object of course the B's are also imported but I do want to the relationship between the objects to be set.
Is there any idea how can I break the infinite recursion without omitting the one side of the reference?
Thanks in advance
I did also try to use statement below according to answers given similar questions but it did not work so I asked the question above.
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "#id")
it does not sufficient to break the circle. You should also add below annotation to the id property of your class.
#JsonProperty("id")
We can try to break the loop either at the Parent end or at the Child end by following 3 ways
Use #JsonManagedReference and #JsonBackReference
Use #JsonIdentityInfo
Use #JsonIgnore
Use #JsonIdentityInfo
#Entity
#Table(name = "nodes")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Node {
...
}
#Entity
#Table(name = "relations")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Relation {
...
}
Refer more in detail here with the working demo at the end.

Hibernate, Spring Data, insert id of table parent on table child

I'm trying insert the id of Person in child table 'Contact'. But the Hibernate stores the value null at fk column.
I perform the mapping of a DTO to the entity, where it already brings the person's data and contact. In the end I have to save the person entity.
There is a table inheritance!
Parent table:
#Entity
#Table
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, columnDefinition = "CHAR(2)", length = 2)
public abstract class Person implements Serializable {
#OneToMany(fetch = FetchType.EAGER, mappedBy = "person")
#Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private #Getter #Setter Set<Contact> contacts;
}
Table Company extends of Person:
#Entity
#Table
#DiscriminatorValue(value="PJ")
public class Company extends Person implements Serializable {
#Column(nullable = false, columnDefinition = "DATE")
private #Getter #Setter LocalDate constitutionDate;
}
And where is the problem!
#Entity
#Table(name = "contact")
#EqualsAndHashCode
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private #Getter Integer id;
#Column(columnDefinition = "VARCHAR(16)", length = 16, nullable = false)
private #Getter #Setter String phoneNumber;
#ManyToOne(fetch = FetchType.LAZY, optional = false,targetEntity=Person.class)
#JoinColumn(name = "person_id", nullable = false, referencedColumnName="id")
private #Getter #Setter Person person;
public Contact() {}
public Contact(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
What am I doing wrong? What's the best strategy?
Excuse me for my poor English!
Can't find nothing obvious that's wrong but let me try some things:
Your cascade annotation on Person class doesn't need the specific Hibernate enumeration You can use like :
#OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, mappedBy = "cliente")
In your ManyToOne annotation on Contact class please try to add:
#ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
BTW, an inheritance relationship between Person and Company doesn't seem logic to me, but that has nothing to do with your stated problem for sure.

Spring Data JPA (Hibernate) is not creating column as autoincrement

Why is this mapping unable to create the column id as autoincrement?
#Entity(name = "user_role")
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false, unique = true)
private Long id;
#OneToOne(cascade = CascadeType.MERGE, targetEntity = Role.class)
#JoinColumn(name = "role_id")
private Role role;
#OneToOne(cascade = CascadeType.MERGE, targetEntity = User.class)
#JoinColumn(name = "user_id")
private User user;
}
Thanks in advance!
To use a AUTO_INCREMENT column in your MySQL, you are supposed to use an IDENTITY strategy:
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true)
private Long id;
//Your code
To learn more check this Link
It is clearly mentioned that
The IDENTITY strategy also generates an automatic value during commit for every new entity object.
Well, just to help people.
The problem was the name of my entity "user_role", I don't know why but after changing the entity name to "userrole" everything worked and the id column was created as AUTOINCREMENT.
Hope this helps!