JPA Eclipse fails to update foreign key on merge() call - java

i've found this problem in a lot of posts but i can't find a solution.
I have one entity:
#Entity
#Table(name="UTENTI")
#NamedQueries({
#NamedQuery(name="Utenti.findAll", query="SELECT u FROM Utenti u"),
#NamedQuery(name="Utenti.findByEmail", query="SELECT u FROM Utenti u WHERE u.userId = :mail")
})
public class Utenti implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="ID_UTENTE", nullable = false)
#GeneratedValue(strategy=GenerationType.AUTO)
private BigDecimal id;
#Column(name="USER_ID",unique=true)
private String userId;
private String cognome;
#Temporal(TemporalType.DATE)
private Date dataDiNascita;
private String nome;
private String password;
private String ruolo;
#OneToMany(mappedBy="user",cascade=CascadeType.ALL)
private List<Form> forms;
#ManyToMany(mappedBy="users",cascade=CascadeType.ALL)
private List<Groups> groups;
#OneToMany(mappedBy="utente",cascade=CascadeType.ALL)
private List<CodicePromozionale> codes;
#OneToMany(mappedBy="owner",cascade=CascadeType.ALL)
private List<PacchettoAcquistato> acquisti;
/*getters and setters*/
and another entity:
#Entity
#Table(name="GROUPS")
public class Groups implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="GROUPID", nullable=false)
private String groupId;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name="USER_GROUP",joinColumns={#JoinColumn(name="GROUPID",referencedColumnName="GROUPID")},inverseJoinColumns={#JoinColumn(name="USERID",referencedColumnName="USER_ID")})
private List<Utenti> users;
if i change userId inside my stateless bean and then call merge like so:
this.user.setUserId(newUserId);
this.em.merge(user);
where this.em is the EntityManager
i get this error:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507- 3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`traveldreamdb`.`user_group`, CONSTRAINT `FK_USER_GROUP_USERID` FOREIGN KEY (`USERID`) REFERENCES `UTENTI` (`USER_ID`))
Error Code: 1451
Call: UPDATE UTENTI SET USER_ID = ? WHERE (ID_UTENTE = ?)
bind => [2 parameters bound]
why this happens if i have specified the cascadeType.ALL?How can i resolve it?

From the exception message, it says you have another table in your database, name is user_group. It has a column user_id. This column is referencing to the user_id column of UTENTI table. So, whenever you are trying to update this value, the other table user_group faces the problem as the reference is updated.

Related

Hibernate 5.2.17: ORA-01797: this operator must be followed by ANY or ALL

I have an Oracle 18.4.0 XE database that I'm trying to access from JPA 2.1, implemented by Hibernate 5.2.17.
I have a ManyToMany connection between 2 entities:
public class PermissionEntity implements Serializable {
private static final long serialVersionUID = -3862680194592486778L;
#Id
#GeneratedValue
private Long id;
#Column(unique = true)
private String permission;
#ManyToMany
private List<RoleEntity> roles;
}
public class RoleEntity implements Serializable {
private static final long serialVersionUID = 8037069621015090165L;
#Column(unique = true)
private String name;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
private List<PermissionEntity> permissions;
}
When trying to run the Spring Data JPA request on PermissionRepository: findAllByPermission(Iterable<String> permissions), I get the following exception:
Error : 1797, Position : 140, Sql = select permission0_.id as id1_0_, permission0_.permission as permission2_0_ from PermissionEntity permission0_ where permission0_.permission=(:1 , :2 ), OriginalSql = select permission0_.id as id1_0_, permission0_.permission as permission2_0_ from PermissionEntity permission0_ where permission0_.permission=(? , ?), Error Msg = ORA-01797: this operator must be followed by ANY or ALL
You are telling the Spring Data Jpa engine to search for Permission where permission is equal to the list. It should use the IN operator so your method name should be:
findAByPermissionIn(Iterable<String> permissions)
Use the 'in' keyword: findAllByPermissionIn(Iterable<String> permissions).
This would produce a query like this: where permission0_.permission IN (:permissions).

JPA: Mapping ManyToMany relationship refers to incorrect column name

This question is related to previous question that I asked yesterday.
I have many-to-many relationship between Employee and SkillSet table, with additional column numberOfYears for each relation
employeeId skillSetId numberOfYears
10 101 2
Since I do not have ID column in EmployeeSkillSet table, I am using #IdClass to define the composite key
#Entity
class Employee {
private #Id Long id;
#OneToMany(mappedBy="employeeId")
private List<EmployeeSkillSet> skillSets;
}
class SkillSet {
private #Id Long id;
}
#IdClass(EmpSkillKey.class)
#Entity
class EmployeeSkillSet {
#Id
#Column("employee_id")
private Long employeeId;
#Id
#Column("skill_id")
private #Id Long skillId;
#ManyToOne
private Employee employee;
private int numberOfYears;
}
class EmpSkillKey{
private int employeeId;
private int skillId;
}
interface EmployeeRepository extends JPARepository{
List<Employee> getEmployeesBySkillSetSkillId(long id);
}
The above JPA repository method works fine and gives me list of Employees as per the skillSet ID. But when I try to iterate over the list and get the EmployeeSkillSet object then it throws error, as it tries to map to incorrect column employee instead of employeeId.
List<Employee> emps = employeeRepository.getEmployeesBySkillSetSkillId(101);
for(Employee e: emps){ // this line throws error
EmployeeSkillSet ess = e.getEmployeeSkillSet();
int n = ess.getNumberOfYears();
}
Query generated is something like this. (I have converted it to Employee use case, cannot share actual query)
select ud.employee_id , ud.employee_id , ud.employee , ud.employee_value , rd.employee_id
from employee_skill_set ud left outer join employee rd
on ud.employee=rd.employee_id
where ud.employee_id=?
Exception
WARN - SqlExceptionHelper - SQL Error: 207, SQLState: ZZZZZ
ERROR - SqlExceptionHelper - Invalid column name 'employee'.
org.hibernate.exception.GenericJDBCException: could not extract ResultSet
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:449)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:202)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:137)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:559)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:261)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:143)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
May be I cannot define #Id employeeId and #ManyToOne employee in same class. But then how to resolve this?
Nevermind, I found out the solution. Annotated the #ManyToOne relation with #JoinColumn and with actual column name. Not sure why it asked for making updatable and insertable as false. Have to get my basics clear :)
#IdClass(EmpSkillKey.class)
#Entity
class EmployeeSkillSet {
#Id
#Column("employee_id")
private Long employeeId;
#Id
#Column("skill_id")
private #Id Long skillId;
#JoinColumn(name="employee_id", insertable=false, updatable=false)
#ManyToOne
private Employee employee;
private int numberOfYears;
}

Update Query using composite PrimaryKey

I'm trying to update a column in a table with a composite primaryKey using Hibernate.
I have written sql preparedStatement for the same.
#Entity
#Table(name = "STUDENT")
Class Student{
#EmbeddedId
private StudentKey studKey;
#Column(name = "STUD_NAM")
private String name;
.....
}
#Embeddable
public class StudentKey implements Serializable {
#Column(name = "STUD_ID")
private int studId;
#Column(name = "R_RUL_BEG_DT")
private java.sql.Date beginDate;
....
}
Query :
update Student set priority=(priority+1) where studKey.studId = ? and priority between ? and ?
I'm Getting the below exception,
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'studKey.studId' in 'where clause'.
Any Suggestions please? I cant use entity objects for update operation (session.saveOrupdate()),
since i will be constructing this query dynamically based on some conditions.

Trying Derived Identifiers using #JoinedColumns, got error Attempt to modify an identity column

This is my sql table structure:
create table TBL_EMPLOYEE_FIVE(
EMP_ID integer generated always as identity(start with 50, increment by 4),
NAME varchar(50),
COUNTRY varchar(50),
MGR_ID integer,
MGR_COUNTRY varchar(50),
constraint PK_COMPOSIT_001AD primary key(EMP_ID,COUNTRY),
constraint FK_COMPO_00123 foreign key(MGR_ID,MGR_COUNTRY) references TBL_EMPLOYEE_FIVE
)
And this is my entity mapping:
#Entity
#Table(name="TBL_EMPLOYEE_FIVE")
#IdClass(EmployeeId.class)
public class EmployeeOne implements Serializable{
public EmployeeOne(){}
public EmployeeOne(String employeeName,String empCountry){
this.empCountry = empCountry;
this.employeeName = employeeName;
}
public EmployeeOne(String employeeName,String empCountry,EmployeeOne manager){
this.empCountry = empCountry;
this.employeeName = employeeName;
this.manager = manager;
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="EMP_ID")
private Integer employeeId;
#Id
#Column(name="COUNTRY")
private String empCountry;
#Column(name="NAME")
private String employeeName;
#ManyToOne( cascade= {CascadeType.PERSIST, CascadeType.PERSIST},
fetch= FetchType.LAZY,
targetEntity=EmployeeOne.class)
#JoinColumns({
#JoinColumn(name="MGR_ID",referencedColumnName="EMP_ID"),
#JoinColumn(name="MGR_COUNTRY",referencedColumnName="COUNTRY")
})
private EmployeeOne manager;
#OneToMany(cascade={CascadeType.PERSIST, CascadeType.PERSIST},mappedBy="manager")
private Set<EmployeeOne> employees;
// getters and setters,
}
This is the the embedded id mapping,
#Embeddable
public class EmployeeId implements Serializable{
public EmployeeId(){}
public EmployeeId(Integer employeeId,String empCountry){
this.employeeId = employeeId;
this.empCountry = empCountry;
}
#Column(name="EMP_ID")
private Integer employeeId;
#Column(name="COUNTRY")
private String empCountry;
// only getters and implementation of hashcode and equals method
}
And this is what I am trying to run in my main method:
EmployeeOne manager = new EmployeeOne("Yousuf Ahmadinejad", "IRAN");
em.persist(manager);
But here i am getting an exception i.e.
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Attempt to modify an identity column 'EMP_ID'.
It's not like i didn't understood the exception,
but why this exception occured in the first place? I already annotated it with #GenerateValue for Empid and I am not setting the empId manually. Does this exception occur because I have combined primary key as empId and country, and than the empId is autogenerated using Identity, hence its giving an exception ?
Can you please tell me whats going wrong
One more thing i want to add here is, if i removed #Column and #Embeddeble annotation for EmployeeId.java, and than run, i get an following exception,
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.entities.derived.EmployeeId.employeeId
So just trying to find the solution to persist employee keeping the autogenerated Id as it is
First Hibernate does not generate id's for composite keys, so you should change EmployeeOne to:
#Id
//#GeneratedValue(strategy=GenerationType.IDENTITY) remove this line
#Column(name="EMP_ID")
private Integer employeeId;
Second that's not how you should implement EmployeeId composite key class. See: https://stackoverflow.com/a/3588400/1981720
Third, the exception is thrown by the database, not Hibernate. Check if you're getting the same exception with another database.

org.hibernate.ObjectNotFoundException issue with using list()

The following query throws the exception:
Query query = session.createQuery("from Associate as a order by a.username asc");
associates = query.list();
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ca.mypkg.model.Associate#0]
If I create an entry in the database with id of 0 it works just fine. I don't really get it because I'm just trying to load all the entries in the db not just a specific one.
Similar questions I've found have been concerned with trying to load an object with a given ID I'm doing no such thing.
Associate class:
#Table(name = "user")
#XmlRootElement(name = "associate")
public class Associate implements Serializable {
private String username;
private String password;
private String firstName;
private String lastName;
private String userType;
private int id;
private String email;
private String isActive;
private Department dept;
private String lastUpdated;
private String associate_type;
// ...
#Id
#GeneratedValue
public int getId() {
return id;
}
#OneToOne
#JoinColumn(name = "dept")
public Department getDept() {
return dept;
}
From my experience this type of error message usually means it does not find joined entity by mentioned id, and not the entity requested in the query (Associate, in your case).
My guess is that Associate class contains a join entity which has primitive type primary key.

Categories

Resources