I'm trying to use Hibernate to map the following relationship:
Each order contains 2 images. When I delete an order I want the images gone as well.
I have two entities, OrderItems and Image and they look like this
public class OrderItems {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="ID")
private Long id;
#Transient
private String language;
#OneToMany(fetch = FetchType.EAGER ,orphanRemoval = true, cascade = CascadeType.ALL, mappedBy = "order")
private List<Image> images ;
}
public class Image implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="ID")
private Long id;
#Column(name = "IMAGE_NAME")
private String name;
#Column(name = "IMAGE_BYTES", unique = false, nullable = true, length = 1000000)
private byte[] image;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "order_id" , nullable = false)
private OrderItems order;
}
Inserting new orders will also insert the coresponding images but when I try to delete an order I get an foreign key constraint error from the tables Image
Am I missing something about Hibernate ? Shouldn't the attribute cascade = CascadeType.ALL do the trick ?
Thanks for taking the time to provide any feedback. Cheers
I already tried OneToMany and ManyToOne unidirectional and bidirectional but I get the same foreign key violation error or my images are not saved at all when I save a new order.
I solved the issue by using Spring to delete an order and automagically it also deleted the images corresponding to that order.
So my first approach of deleting orders by executing sql queries directly on the DB was the issue.
Try like this
#OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
#ManyToOne(optional = false, fetch = FetchType.EAGER)
#JoinColumn(name = "order_id", nullable = false)
Related
I know this question has been asked many times but none of the solution is working for me.
So I have a Parent class :
class User{
#Id
#NotNull
#Column(name = "`UserId`", nullable = false)
private Long userId;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
#JoinColumn(name = "`UserId`")
private Set<Phone> phoneList;
}
And a child class:
class Phone {
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "`UserId`")
private User user;
}
Now when I received a update for User class with new phone list, I want to remove all the old phones and add new phones. Please note that this all operation is happening in same #Transactional.
Solution I tried:
user.getPhoneList().clear()
user.getPhoneList().addAll(new phone list)
When I try the above logic, Hibernate is trying to set old phone with userId as null. At this position I am getting DataIntegrityViolation as userId in Phone table is non null column.
Please provide any appropriate solution which can work here.
Hhhmmm... I have the exact same logic and it works fine by me. Here are my classes
#Data
#Entity
public class ProductReference {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#OneToMany(mappedBy = "productReference", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE, orphanRemoval = true)
private Set<Attribute> attributes = new HashSet<>();
}
The only difference I see is the CascadeType.REMOVE
#Data
#Entity
public class Attribute {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#ManyToOne
private ProductReference productReference;
}
My deletion:
productReference.getAttributes().clear();
Which Hibernate version you have? by me it is org.hibernate.Version - HHH000412: Hibernate Core {5.4.10.Final}
I am trying to build a bidirectional one to many relationship with the spring data jpa but the list annotated with #onetomany always return one element.
Here is the code for my entities(setters and getters omitted):
#Entity
#Table(name = "sdk_sdk")
public class SDKEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String version;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "sdk")
#OrderBy("order ASC")
private List<SDKFileEntity> fileEntities;
}
And the second entity:
#Entity
#Table(name = "sdk_file")
public class SDKFileEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String fileType;
private Integer sdkId;
public SDKFileEntity() {
}
#ManyToOne
#JoinColumn(name = "id", insertable = false, updatable = false)
private SDKEntity sdk;
I am trying to have a manytoone mapping where the sdkId corresponds to the id from the SDKEntity class.
Whenever I try to get the sdkfiles from the sdkEntity using spring's repository, the size of the list is always 1.
So for example:
SDKEntity entity=repository.findOne(foo);
List<SDKFileEntity> files=entity.getFileEntities();
here the size of files is 1, I have to delete the first element from the database to obtain the second element.
For me the reason here was that a parent entity implemented equals and hashcode
and unfortunately in a way that all existing entities were equal.
And non of the child entities implemented it herself.
So then the #OneToMany relation returned only the first element.
Took me quite some time.
This part of Code looks suspicious
#ManyToOne
#JoinColumn(name = "id", insertable = false, updatable = false)
private SDKEntity sdk;
name = "id" it should be actual column name as written in database column name like this
#JoinColumn(name = "VISIT_ID", referencedColumnName = "ID")
#ManyToOne
private Visit visitId;
I have two entities that used to be linked by a one to many relation but now they are linked by a many to many relation declared as follow :
SalesTeam entity :
#Entity
#Table(name = "SALES_TEAMS")
public class SalesTeam {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH, CascadeType.PERSIST})
#JoinTable(name = "WORKFLOW_FOR_SALESTEAM", inverseJoinColumns = {
#JoinColumn(name = "WFC_ID")
})
private List<WorkFlowCode> workFlowCodes = new ArrayList<>();
}
And the WorkFlowCode entity :
#Entity
#Table(name = "WORK_FLOW_CODE")
public class WorkFlowCode {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH, CascadeType.PERSIST})
#JoinTable(name = "WORKFLOW_FOR_SALESTEAM", inverseJoinColumns = {
#JoinColumn(name = "ST_ID")
})
private List<SalesTeam> salesteam = new ArrayList<>();
}
As I said the relation use to be one SalesTeam for several workflow codes but the requirement change and now it need to be a many to many relation. So I had a relation table and remove the former SALES_TEAM_ID column from the WORK_FLOW_CODE table. The problem is that now I always get an error when I try to get the WorkFlowCode from a SalesTeam. It appears that hibernate still adds the removed column to the query thus the relation had changed and nothing is left from the former relation description.
Here is the hibernate generated query :
select workflowco0_.SALES_TEAMS_ID as SALES_TE3_13_0_, workflowco0_.WFC_ID as WFC_ID4_16_0_, workflowco1_.ID as ID1_17_1_ from WORKFLOW_FOR_SALESTEAM workflowco0_ inner join WORK_FLOW_CODE workflowco1_ on workflowco0_.WFC_ID=workflowco1_.ID where workflowco0_.SALES_TEAMS_ID=?
As you can see the former SALES_TEAM_ID from WORK_FLOW_CODE table is still there.
How can I remove it ?
Thx
First of all, sorry for my English.
So, I'm working with MS SQL Server with hibernate and i faced with a problem.
I have next mapping of one of the tables in my DB:
#Entity(name = " ... ")
public class Entity extends BaseEntity implements Comparable {
#Id
#Column(name = "...")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "parent_entity_id", insertable = false, updatable = false)
private Integer parentId;
#ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
#JoinColumn(name = "parent_entity_id")
private Entity parent;
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = {CascadeType.REMOVE}, orphanRemoval = true)
private Set<Entity> children;
//other fields, setters, getters
}
That means, that my Entity objects can have children, which are also an Entity objects.
So, my problems is that I can't correctly delete parent with all his children. When I try to remove parent, i get an SQL error:
The DELETE statement conflicted with the SAME TABLE REFERENCE
So, any ideas, how to solve this problem?
You have a foreign key defined between parent_entity_id and id. Set it to allow cascading deletes: deleting a parent will delete all it's children, and all their children et cetera.
Be sure you actually want this to happen!
I'm looking how to map in JPA a hashmap with its value being a list.
I've 2 entities:
EntityA {
#Id
#GeneratedValue
private Integer id;
#MapKey(name = "nature")
#MapKeyEnumerated(EnumType.STRING)
#OneToMany(mappedBy = "entityA", cascade = CascadeType.ALL)
private Map<NatureEnum, List<EntityB>> mapEntityB = new HashMap<NatureEnum, List<EntityB>>();
}
EntityB {
#Id
#GeneratedValue
private Integer id;
#ManyToOne
#JoinColumn(name = "ID_ENTITYA", nullable = false)
private EntityA entityA;
#Column(name = "NATURE", nullable = false)
#Enumerated(EnumType.STRING)
private NatureEnum nature;
}
You will have guessed that of course the map doesn't work as it's missing something telling it it's not just one EntityB in it.
The rest does work and if i change the map by a regular List it works fine.
So how can i manage to "group by" my EntityB in one list depending on the value of Nature?
Thanks in advance for your help.