How can I add a subselect to result in jpa query - jpa

I have an Spring boot app with an entity Person with a list of that persons events on.
Like this.
public class Person....
private Long id;
private String name;
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "person_events", joinColumns = #JoinColumn(name = "person_id"))
private List<String> personEvents = new ArrayList<>();
Now when I select I want to select the result into a dto like this.
#Query("""
select new com.....dtos.PersonDto(p.name, p.events) from Person p
where p.name = (:name)
""")
Set<PersonDto> findPersonsByName(String name);
My repository fails because it cant generate the sql. How can I achieve this?

Few things you are doing can be improved like:
Instead of constructor select you can use interface projection
Set<PersonDto> findPersonsByName(String name);
Since you are doing a select on single item the result will be single object.
so please change it to
PersonDTO findPersonsByName(String name);
Please find my complete answer below:
package com.example.demo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
#RestController
#RequestMapping("/person")
public class PersonController {
private final PersonService personService;
#Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}
#GetMapping
public Iterable<Person> list() {
return personService.list();
}
#PostMapping
public Person create(#RequestBody Person car) {
return personService.save(car);
}
#GetMapping(path = "/by")
public PersonDTO getPersonByName(#RequestParam(value = "name") String name) {
return personService.findPersonByName(name);
}
}
#Getter
#Setter
#ToString
#Entity
class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "person_events", joinColumns = #JoinColumn(name = "person_id"))
private List<String> personEvents = new ArrayList<>();
}
#Service
class PersonService {
private final PersonRepository personRepository;
#Autowired
PersonService(PersonRepository personRepository) {
this.personRepository = personRepository;
}
#Transactional
public Person save(Person person) {
return personRepository.save(person);
}
#Transactional(readOnly = true)
public Iterable<Person> list() {
return personRepository.findAll();
}
#Transactional(readOnly = true)
public PersonDTO findPersonByName(String name) {
return personRepository.findPersonsByName(name);
}
}
interface PersonDTO {
String getName();
Collection<String> getPersonEvents();
}
#Repository
interface PersonRepository extends JpaRepository<Person, Integer> {
PersonDTO findPersonsByName(String name);
}

Related

Why does spring jpa ignore javax.persistence.FetchType.LAZY and javax.persistence.NamedEntityGraph?

I have a basic "Department"/"Employee" example.
Full example here (in master branch) : https://github.com/granadacoder/jpa-simple-example-one.git
If you setup 4 environment variables (listed in the README), the code is runnable/debuggable.
For my "findAll()" method, I am trying to only bring back the scalars of the Department entity. (key and name). Aka, I do NOT want any child Employees to be tacked onto the Department .. when I do a findAll().
I have tried using an name EntityGraph, but it is not working (I still get the full object graph)
I am using FetchType.LAZY as well. (which should have been enough IMHO)... And I am not calling (department) .getEmployees at all.
But I took the extra step of defining and using "departmentJustScalarsEntityGraphName".
#EntityGraph("departmentJustScalarsEntityGraphName")
List<Department> findAll();
The above is loading the entire graph (all department scalar AND the employees) and doing it in an N+1 manner. :(
The #EntityGraph should only be loading the key and name for the findAll() method.
If you find the code comment
/* right here, desperately hoping for each Department in the "entities" to NOT have employees hydrated */
you can put the debugger there and see the issue.
Note, that when I do a "find by single" (findById(key) or findDepartmentByDepartmentNameEquals(name))......I DO want the employees. So answers that broad stroke disassociate the Employees are not ideal.
No matter what I've tried, I'm getting the N+1 issue. (The sample seed data has three Departments.)
Hibernate: select department0_.DepartmentKey as departme1_0_, department0_.CreateOffsetDateTime as createof2_0_, department0_.DepartmentName as departme3_0_ from DepartmentTable department0_
Hibernate: select employees0_.DepartmentForeignKey as departme6_1_0_, employees0_.EmployeeKey as employee1_1_0_, employees0_.EmployeeKey as employee1_1_1_, employees0_.CreateOffsetDateTime as createof2_1_1_, employees0_.FirstName as firstnam3_1_1_, employees0_.LastName as lastname4_1_1_, employees0_.DepartmentForeignKey as departme6_1_1_, employees0_.Ssn as ssn5_1_1_ from EmployeeTable employees0_ where employees0_.DepartmentForeignKey=?
Hibernate: select employees0_.DepartmentForeignKey as departme6_1_0_, employees0_.EmployeeKey as employee1_1_0_, employees0_.EmployeeKey as employee1_1_1_, employees0_.CreateOffsetDateTime as createof2_1_1_, employees0_.FirstName as firstnam3_1_1_, employees0_.LastName as lastname4_1_1_, employees0_.DepartmentForeignKey as departme6_1_1_, employees0_.Ssn as ssn5_1_1_ from EmployeeTable employees0_ where employees0_.DepartmentForeignKey=?
Hibernate: select employees0_.DepartmentForeignKey as departme6_1_0_, employees0_.EmployeeKey as employee1_1_0_, employees0_.EmployeeKey as employee1_1_1_, employees0_.CreateOffsetDateTime as createof2_1_1_, employees0_.FirstName as firstnam3_1_1_, employees0_.LastName as lastname4_1_1_, employees0_.DepartmentForeignKey as departme6_1_1_, employees0_.Ssn as ssn5_1_1_ from EmployeeTable employees0_ where employees0_.DepartmentForeignKey=?
Here are the main code components:
Department.java
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.mycompany.organizationdemo.domain.constants.OrmConstants;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.io.Serializable;
import java.time.OffsetDateTime;
import java.util.LinkedHashSet;
import java.util.Set;
#Entity
#NamedEntityGraphs({
#NamedEntityGraph(name = "departmentJustScalarsEntityGraphName", attributeNodes = {
#NamedAttributeNode("departmentKey"),
#NamedAttributeNode("departmentName")})
})
#Table(name = "DepartmentTable")
public class Department implements Serializable {
#Id
#Column(name = "DepartmentKey", unique = true)
#GeneratedValue(strategy = GenerationType.AUTO)
private long departmentKey;
#Column(name = "DepartmentName", unique = true)
private String departmentName;
#Column(name = "CreateOffsetDateTime", columnDefinition = OrmConstants.OffsetDateTimeColumnDefinition)
private OffsetDateTime createOffsetDateTime;
//region Navigation
#OneToMany(
mappedBy = "parentDepartment",
cascade = CascadeType.REMOVE,
orphanRemoval = true,
fetch = FetchType.LAZY /* Lazy or Eager here */
)
private Set<Employee> employees = new LinkedHashSet<>();
//endregion
public long getDepartmentKey() {
return departmentKey;
}
public void setDepartmentKey(long departmentKey) {
this.departmentKey = departmentKey;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public OffsetDateTime getCreateOffsetDateTime() {
return createOffsetDateTime;
}
public void setCreateOffsetDateTime(OffsetDateTime createOffsetDateTime) {
this.createOffsetDateTime = createOffsetDateTime;
}
//region Navigation
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
//endregion
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Department that = (Department) o;
return new org.apache.commons.lang3.builder.EqualsBuilder()
.append(departmentKey, that.departmentKey)
.append(departmentName, that.departmentName)
.isEquals();
}
#Override
public int hashCode() {
return new org.apache.commons.lang3.builder.HashCodeBuilder(17, 37)
.append(departmentKey)
.append(departmentName)
.toHashCode();
}
}
Employee.java
import com.mycompany.organizationdemo.domain.constants.OrmConstants;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.io.Serializable;
import java.time.OffsetDateTime;
#Entity
#Table(name = "EmployeeTable")
public class Employee implements Serializable {
#Id
#Column(name = "EmployeeKey", unique = true)
#GeneratedValue(strategy = GenerationType.AUTO)
private long employeeKey;
#Column(name = "Ssn")
private String ssn;
#Column(name = "LastName")
private String lastName;
#Column(name = "FirstName")
private String firstName;
#Column(name = "CreateOffsetDateTime", columnDefinition = OrmConstants.OffsetDateTimeColumnDefinition)
private OffsetDateTime createOffsetDateTime;
//region Navigation
#ManyToOne(fetch = FetchType.LAZY, targetEntity = Department.class)//, cascade = CascadeType.REMOVE)
#JoinColumn(name = "DepartmentForeignKey")
private Department parentDepartment;
//endregion
public long getEmployeeKey() {
return employeeKey;
}
public void setEmployeeKey(long departmentKey) {
this.employeeKey = departmentKey;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public OffsetDateTime getCreateOffsetDateTime() {
return createOffsetDateTime;
}
public void setCreateOffsetDateTime(OffsetDateTime createOffsetDateTime) {
this.createOffsetDateTime = createOffsetDateTime;
}
//region Navigation
public Department getParentDepartment() {
return parentDepartment;
}
public void setParentDepartment(Department parentDepartment) {
this.parentDepartment = parentDepartment;
}
//endregion
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return new EqualsBuilder()
.append(employeeKey, employee.employeeKey)
.append(ssn, employee.ssn)
.isEquals();
}
#Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(employeeKey)
.append(ssn)
.toHashCode();
}
}
Spring JPA
import com.mycompany.organizationdemo.domain.entities.Department;
import com.mycompany.organizationdemo.domaindatalayer.interfaces.IDepartmentRepository;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import javax.transaction.Transactional;
import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface DepartmentJpaRepository extends JpaRepository<Department, Long>, IDepartmentRepository {
#EntityGraph("departmentJustScalarsEntityGraphName")
List<Department> findAll();
#Query("SELECT d FROM Department d LEFT JOIN FETCH d.employees WHERE d.departmentName = :departmentName") /* this works because departmentName is a UNIQUE constraint...otherwise it might give back duplicate parents (Departments) */
Optional<Department> findDepartmentByDepartmentNameEquals(#Param("departmentName") String departmentName);
/* note the below, this is "lookup strategy". see https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods */
Collection<Department> findByCreateOffsetDateTimeBefore(OffsetDateTime zdt);
//#Query("SELECT d FROM Department d LEFT JOIN FETCH d.employees WHERE d.departmentKey IN ?1") /* here a Query will bring back repeat parent (Department) rows */
#EntityGraph(attributePaths = {"employees"})
Collection<Department> findDepartmentByDepartmentKeyIn(Set<Long> departmentKeys);
#Modifying
#Transactional
int deleteDepartmentByDepartmentKey(long departmentKey); /* suffers from N+1 problem */
}
and the repository (plain jane) interface
import com.mycompany.organizationdemo.domain.entities.Department;
import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface IDepartmentRepository {
List<Department> findAll();
Optional<Department> findById(long key);
Optional<Department> findDepartmentByDepartmentNameEquals(String departmentName);
Collection<Department> findByCreateOffsetDateTimeBefore(OffsetDateTime zdt);
Collection<Department> findDepartmentByDepartmentKeyIn(Set<Long> departmentKeys);
Department save(Department item);
int deleteDepartmentByDepartmentKey(long departmentKey);
}
I have found this:
Spring Data JPARepository: How to conditionally fetch children entites
and this:
https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm
Spring Boot is fairly new. (from gradle settings in the project)
spring_plugin_version = '2.2.6.RELEASE'
springBootVersion = '2.2.6.RELEASE'
slf4jVersion = "1.7.25"
javaxInjectVersion = "1"
javaxPersistenceApiVersion = "2.2"
junitVersion = "4.12"
mockitoVersion = "3.3.0"
jacksonAnnotationsVersion = "2.11.0"
modelMapperVersion = "2.3.7"
commonsLangVersion = '3.7'
PS
I'm also using the "convert to Dto" trick (as seen here) : https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application but the Department(orm-entity) is already hydrated by that point. :(

#ManyToOne seems not working as i expect it to be

I'm working with many-to-one relationship between my two tables(Employee and Department) in which any Employee can work in more than one department. I used the #ManyToOne annotation on the Department object field which I created in Employee entity class. Now when I persist the Employee entity with a particular department, it works fine but when I try to persist another Employee entity with the same department, it creates a new Department entity with the same name and persists it with different id. What I expect it to do is that when I persist an Employee entity with already persisted department, it should just update the foriegn key of the Employee entity to point the id of that department. Sorry if I didnt got the many-to-one concept totally.
EMPLOYEE entity
package com.test.domain;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.TableGenerator;
#Entity
public class Employee {
#TableGenerator(name="Empl_Gen", table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", initialValue=0, allocationSize=1)
#Id#GeneratedValue(generator="Empl_Gen",strategy=GenerationType.TABLE)
private Long id;
private String Name;
private String Country;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="DEPT_ID")
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getCountry() {
return Country;
}
public void setCountry(String country) {
Country = country;
}
}
DEPARTMENT entity
package com.test.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.TableGenerator;
#Entity
public class Department {
#TableGenerator(name="DEP_GEN",table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", pkColumnValue="DEP_GEN",initialValue=0,allocationSize=1)
#Id#GeneratedValue(strategy=GenerationType.TABLE,generator="DEP_GEN")
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.test.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.domain.Employee;
import com.test.service.EmployeeService;
/**
* Handles requests for the application home page.
*/
#Controller
#RequestMapping("/addEmployee")
public class HomeController {
#Autowired
EmployeeService service;
#RequestMapping(method=RequestMethod.GET)
public String getform(Model model)
{
model.addAttribute("employee",new Employee());
return "home";
}
#RequestMapping(method=RequestMethod.POST)
public String setform(Employee employee)
{
service.save(employee);
return"success";
}
}
package com.test.dao;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.test.domain.Employee;
#Repository
#Transactional
public class Employeedaoimpl implements Employeedao
{
#PersistenceContext
EntityManager manager;
#Override
public void save(Employee employee) {
manager.persist(employee);
}
}
Try this:
#TableGenerator(name="DEP_GEN",table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", pkColumnValue="DEP_GEN",initialValue=0,allocationSize=1)
#Id#GeneratedValue(strategy=GenerationType.TABLE,generator="DEP_GEN")
#Column(name = "DEPT_ID")
private Long id;

Convert String or int To Enum in JPA

I don't know how I can persist an entity(with enum) to the database.
When I fill my form like this;
form.setTypZamowienia(SlownikZamowienie.SENIOR)
then 666 is stored in the database. But when I try like this;
form.setTypZamowienia(SlownikZamowienie.valueOf(request.getParameter("typKlienta").trim()));
0 is stored in the database.
How do I make this work?
For any help I will be very grateful.
My enum :
public enum SlownikZamowienie
{
JUNIOR(42),
SENIOR(666),
PRINCIPAL(31416);
private final int wartosc;
SlownikZamowienie(int wartosc) {
this.wartosc = wartosc;
}
}
My Entity:
package test.jpa.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import test.enums.SlownikZamowienie;
#Entity
#Table(name="Piess")
public class Pies implements Serializable {
private static final Long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
int id;
#Column(name = "imie")
String imie;
#Enumerated
#Column(name = "rasa")
SlownikZamowienie typzamowienia;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
public SlownikZamowienie getTypzamowienia() {
return typzamowienia;
}
public void setTypzamowienia(SlownikZamowienie typzamowienia) {
this.typzamowienia = typzamowienia;
}
}
As of JPA 2.1 you can use an attribute converter (known as a UserType in the Hibernate world). See these two articles for details on how to implement such a solution:
www.thoughts-on-java.org/jpa-21-type-converter-better-way-to/
www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/

HTTP Status 500 - Request processing failed; nested exception is Exception [EclipseLink-4002]

I'am working with JPA eclipselink at the moment and like to connect to my Database with Eclipselink
I have some classes for de Tables in My database and a Query to get my Entries:
final Query query = entityManager.createQuery("SELECT q FROM FDC_DBCHANGE q ORDER BY q.CHANGE_ID");
I made some classes for my tables:
FDC_DBCHANGE
package com.bechtle.dbchanges.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class FDC_DBCHANGE {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private long CHANGE_ID;
private String CHANGE_NAME;
private String CHANGE_DATE;
private int CHANGE_NUMBER;
#OneToMany(mappedBy = "FDC_DBCHANGE")
private final List<FDC_EXECUTED> checkBoxes = new ArrayList<FDC_EXECUTED>();
public String getChangeName() {
return CHANGE_NAME;
}
public void setChangeName(final String pChangeName) {
CHANGE_NAME = pChangeName;
}
public String getChangeDate() {
return CHANGE_DATE;
}
public void setChangeDate(final String pChangeDate) {
CHANGE_DATE = pChangeDate;
}
public int getChangeNumber() {
return CHANGE_NUMBER;
}
public void setChangeNumber(final int pChangeNumber) {
CHANGE_NUMBER = pChangeNumber;
}
public List<FDC_EXECUTED> getCheckBoxes() {
return checkBoxes;
}
#Override
public String toString() {
return "FDC_DBCHANGE [CHANGE_NAME=" + CHANGE_NAME + ", CHANGE_DATE="
+ CHANGE_DATE + "CHANGE_NUMBER=" + CHANGE_NUMBER + "]";
}
}
FDC_EXECUTED
package com.bechtle.dbchanges.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
#Entity
public class FDC_EXECUTED {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private int ENTRY_ID;
private FDC_DBCHANGE FDC_DBCHANGE;
private FDC_SYSTEM FDC_SYSTEM;
#OneToOne
#JoinColumn
public FDC_DBCHANGE getDbChange() {
return FDC_DBCHANGE;
}
public void setDbChange(final FDC_DBCHANGE pDbChange) {
FDC_DBCHANGE = pDbChange;
}
#OneToOne
#JoinColumn
public FDC_SYSTEM getSystem() {
return FDC_SYSTEM;
}
public void setSystem(final FDC_SYSTEM pSystem) {
FDC_SYSTEM = pSystem;
}
}
and FDC_SYSTEM
package com.bechtle.dbchanges.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class FDC_SYSTEM {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private int SYSTEM_ID;
private String NAME;
private FDC_EXECUTED fdcexecuted;
public String getName() {
return NAME;
}
public void setName(final String pName) {
NAME = pName;
}
#OneToMany(mappedBy = "FED_SYSTEM")
public FDC_EXECUTED getExecuted() {
return fdcexecuted;
}
public void setExecuted(final FDC_EXECUTED pExecuted) {
fdcexecuted = pExecuted;
}
}
When I run it on my Tomcat there is this Exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "FDC_DBCHANGE_CHANGE_ID": invalid identifier
Error Code: 904
Call: SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)
bind => [1 parameter bound]
Query: ReadAllQuery(name="checkBoxes" referenceClass=FDC_EXECUTED sql="SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)")
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:932)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:816)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
Eclipselink tries to run the SQL Statement SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)
instead of SELECT ENTRY_ID, CHANGE_ID, SYSTEM_ID FROM FDC_EXECUTED WHERE (CHANGE_ID = ?)
I don't konw why...
I hope someone can help me and sorry for my bad english...
obsidianfarmer
Ok, problem solved, its cause Eclipselink needs an OID I have no acces to, that was the problem...

entity association in java

I am trying to get rid of this error:
Exception Description: [class utilisateurs.modeles.Utilisateur] uses a non-entity [class java.util.Collection] as target entity in the relationship attribute [field adresses].
at org.eclipse.persistence.exceptions.ValidationException.nonEntityTargetInRelationship(ValidationException.java:1343)
.........
org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:526)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1320)
... 36 more
with the following entity:
utilisateurs.modeles;
import adresses.Adresse;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
#Entity(name="Utilisateur")
public class Utilisateur implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public void setAdresses(Collection<Adresse> adresses) {
this.adresses = adresses;
}
private String firstname;
private String lastname;
private String login;
#ManyToOne(cascade=CascadeType.PERSIST)
private Collection<Adresse> adresses;
public Collection<Adresse> getAdresses() {
return adresses;
}
public Utilisateur() {
}
public Utilisateur(final String firstname, final String lastname, final String login) {
this.firstname = firstname;
this.lastname = lastname;
this.login = login;
}
//getters and setters here
#Override
public int hashCode() {
int hash = 0;
hash += (int) id;
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Utilisateur)) {
return false;
}
Utilisateur other = (Utilisateur) object;
if (this.id != other.id) {
return false;
}
return true;
}
}
If you have any idea please.
Adresse is not an Entity, maybe you just forgot the #Entity annotation on that class?
The #ManyToOne annotation defines a relationship between entities.