Hallo I have an entity with a #ManyToOne Relations ship
#Entity
public class TerminEntity extends AbstractEntity implements Serializable {
#ManyToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "PERSON_ID")
private PersonEntity person;
#MappedSuperclass
public abstract class AbstractEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "termineIdGenerator")
#SequenceGenerator(name="termineIdGenerator", sequenceName = "SEQ_TERMINVERWALTUNG")
private Long id;
When I try to persist a TerminEntity with an PersonEntity which is not already present in the database I get
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: TerminEntity(person=PersonEntity
Why? What is wrong with the #ManyToOne(cascade = CascadeType.PERSIST) annotation?
Running on Oracle Weblogic 12c
I don't know why but after changing the annotation to
#ManyToOne(optional = false, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
#JoinColumn(name = "PERSON_ID", referencedColumnName = "ID", nullable = false)
the persist works.
Related
I am working on simple spring security demo and want to put user and role info into db. Here is the simple structure of my entity.
#Entity
#Table(name = "users")
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private Long userId;
#OneToMany(mappedBy = "users", fetch = FetchType.LAZY, orphanRemoval=true, cascade = CascadeType.ALL)
private List<UserRoleMapping> userRoleMapping;
}
//
#Entity
#Table(name = "user_role_mapping")
public class UserRoleMapping {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_role_mapping_id")
private Long userRoleMappingId;
#ManyToOne(fetch = FetchType.LAZY)
private Users users;
#ManyToOne(fetch = FetchType.LAZY)
private UserRole userRole;
}
//
#Entity
#Table(name = "users_role")
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "role_id")
private Long roleId;
#Column(name = "role")
private String role;
#Column(name = "role_desc")
private String roleDesc;
#OneToMany(mappedBy = "userRole", fetch = FetchType.LAZY, orphanRemoval=true)
private List<UserRoleMapping> userRoleMapping;
}
In my use case, I have to make sure when the user is created then I have to insert subsequence userRoleMapping. And If the userRole is removed then the userRoleMapping must be deleted as well.
So I put CascadeType.ALL and orphanRemoval=true in users entity, and orphanRemoval=true in userRole entity.
However, when I run userRoleRepository.delete(userRole). I have dataIntegrityViolationException.
I did some researches on it and understand it is a kind of jpa constrains to make sure we delete the parents (users) as well.
May I ask if there are any workaround for my use case?
Thanks
Here is the solution to my use cases. Instead of using OneToMany in both entity, I should use ManyToMany relationship. And it is quite make sense as I don't care (for now) the mapping in java logic. Here is my code
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private Long userId;
#ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
#JoinTable
private Set<UserRole> userRole;
}
//
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "role_id")
private Long roleId;
#Column(name = "role")
private String role;
#Column(name = "role_desc")
private String roleDesc;
#OneToMany(mappedBy = "userRole", fetch = FetchType.LAZY)
private Set<Users> users;
}
I need help with resolving our problem with naming FK in JPA. We have one embeddable entity e.g. Foo which is used as collection in another one entity Bar.
embeddable entity:
#Embeddable
public class Foo{
#Column(name = "foo1")
private String foo1;
#Column(name = "foo2")
private String foo2;
}
main entity:
#Entity
#Table(name = "Bar")
public class Bar {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
#Id
private Long id;
#ElementCollection
#CollectionTable(name = "foos", joinColumns = #JoinColumn(name = "bar_id", foreignKey = #ForeignKey(name = "foo_bar_fk"), nullable = false))
private List<Bar> bars;
}
When I generated tables in database (postgres) foreign key is called fdk44l345k64 instead foo_bar_fk. Can you tell me how to fix it? Thanks.
Hi there I am new to JPA and got following error as
In attribute 'employees', the "mapped by" value 'project_id' cannot be resolved to an attribute on the target entity.
with following code
#Entity
#Table(name = "project")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "project_id")
protected int id;
#Column(name = "project_name")
protected String name;
#ManyToMany(mappedBy = "project_id")
protected List<Employee> employees;
#Entity
#Table(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "employee_id")
protected int id;
#Column(name = "employee_name")
protected String name;
#ManyToMany(targetEntity = Project.class)
#JoinTable(name = "project_employee", joinColumns = #JoinColumn(name = "project_id"), inverseJoinColumns = #JoinColumn(name = "employee_id"))
protected List<Project> projects;
Here If I am trying to map the inverse entity it says that attribute not found.
Please help me to solve this
As the message says your mappedBy value is wrong. It should be the name of the FIELD/PROPERTY on the other side of the BIDIRECTIONAL relation, that links back to this class. e.g Project.employees claims to link back via field Employee.project_id, yet that doesn't exist. Instead mappedBy should be projects. This would be found in any basic JPA docs
The situation: I have a class with a Map like this:
#Entity
public class Bar {
#Id
#GeneratedValue
private Long id;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "fooMap",
joinColumns = #JoinColumn(name = "One_ID", referencedColumnName = "ID") ,
inverseJoinColumns = #JoinColumn(name = "Two_ID", referencedColumnName = "ID") )
#MapKeyJoinColumn(name = "Bar")
private Map<FooOne, FooTwo> fooMap;
}
with key/value-classes like this (FooTwo looks more or less the same):
#Entity
public class FooOne {
#Id
#GeneratedValue
private Long id;
#Basic
private String name;
If I populate the map and try to persist it, I get the following exception:
UnitOfWork(117839394)--java.lang.IllegalStateException: During synchronization >a new object was found through a relationship that was not marked cascade >PERSIST: jpa.test.minimalExample.FooOne#2e4389ed.
because JPA cascades only to the target of the -toMany association which is the value entity.
Does JPA in general or EclipseLink as implementation offer any form of annotation to cascade actions to the key class of this map? What are my options here ?
I know adding a reference to FooOne in the FooTwo-class works (like this):
#Entity
public class FooTwo {
#Id
#GeneratedValue
private Long id;
#OneToOne(cascade = cascadeType.ALL)
private FooOne foo1;
}
I would rather not add any additional fields to my classes if I can avoid it.
hi have two tables in picture table a and table b as follows :
#Entity
#Table(name = "A")
public class A implements Serializable {
#Id
#SequenceGenerator(name = "JOURNAL_CATEGORY_ID_GENERATOR", allocationSize = 1, sequenceName = "clm_jounal_category_config_seq")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "JOURNAL_CATEGORY_ID_GENERATOR")
#Column(name = "CLAIM_ID")
private String claimId;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
private List<ClaimDTLS> claimDetails;
}
B Primary Key:
#Embeddable
public class BPK implements Serializable {
#Column(name = "code")
private String code;
#Column(name = "CLAIM_ID")
private String claimId;
}
B Entity:
#Entity
#Table(name = "B")
public class B implements Serializable {
#EmbeddedId
protected BPK bpk;
#Column(name = "name")
private String name;
#MapsId("country_code")
#JoinColumn(name = "claimId", referencedColumnName = "claimId", insertable = false, updatable = false)
#ManyToOne
private A a;
}
when i try to persist object of A type in Db the value of table b claim id is not set and is intialized with zero.
Also primary key of table A is generated with a oracle sequence.
any help will be welcomed.
thanks in advance
Sequence values are numbers and when JPA use them as a generator it call the setter method of the entity PK. Now, you defined your PK as a string while you use a sequence and so no matching setter can be found. Change the type of you PK to be Long and things shall work