I'm very new to Java Spring and have a little Problem.
I wan't to send the employee_id (from employees entity) to assignment entity in the body part (in Postman). Currently it's working, because I'm sending the employee_id as a PathVariable and I'm sending the assignment data with ResponseBody.
#PostMapping("/add/{employee_id}")
public void addEmployee(#PathVariable(value = "employee_id", required = false) Long employee_id,
#RequestBody Assignment a) {
Employee employeeById = employeeRepository.findById(employee_id)
.orElseThrow(() -> new RuntimeException("Employee not found"));
a.setEmployee(employeeById);
assignmentRepository.addAssignment(a);
}
It is working with the url localhost:8080/add/35. 35 is the employee_id and the assignment data can be send in the Body (of Postman). What I want to do is, to send the employee_id in the body too (so the url should only be /add), but I could not get it to work.
Like that:
{
"employee_id": 35,
"title": "abc"
}
Edited:
Assignment.java
public class Assignment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToOne(optional = false)
#JoinColumn(name = "employee_id", nullable = false)
private Employee employee;
#Size(min = 3, max = 50)
private String assignment_title;
public Assignment() {
}
public Assignment(String assignment_title) {
super();
this.assignment_title = assignment_title;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAssignment_title() {
return assignment_title;
}
public void setAssignment_title(String assignment_title) {
this.assignment_title = assignment_title;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
AssignmentService.java
public void addAssignment(Assignment e) {
AssignmentRepository.save(e);
}
AssignmentRepository.java
public interface AssignmentRepository extends CrudRepository<Assignment, Integer>{
}
Employee.java
public class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToOne(optional = false)
#JoinColumn(name = "user_id", nullable = false)
private User user;
#Size(min=3, max = 100)
private String title;
#Size(min=3, max = 50)
private String staff;
private Long degree;
public Employee() {}
public Employee( String title, String staff, Long degree) {
super();
this.title = title;
this.staff = staff;
this.degree = degree;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStaff() {
return staff;
}
public void setStaff(String staff) {
this.staff = staff;
}
public Long getDegree() {
return degree;
}
public void setDegree(Long degree) {
this.degree = degree;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
EmployeeRepository.java
public interface EmployeeRepository extends CrudRepository<Employee, Integer>{
Optional<Employee> findById(Long id);
}
Thanks for your help in advance!
You need to ensure your body type Assignment has such property like
public class Assignment {
public Long employee_id;
// ommitted
}
And get it in your method like
#PostMapping("/add")
public void addEmployee(#PathVariable(value = "employee_id", required = false) Long employee_id, #RequestBody Assignment a) {
Long employee_id = a.employee_id;
Employee employeeById = employeeRepository.findById(employee_id)
.orElseThrow(() -> new RuntimeException("Employee not found"));
a.setEmployee(employeeById);
assignmentRepository.addAssignment(a);
}
But such implementation does not respect HTTP standards.
Please consider that your actual implementation almost respect those standards and you should rename your API this way : POST URL/v1/employees/{employee_id}
This blog explains those standards
EDIT with provided specifications:
#PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
public void addEmployee(#PathVariable(value = "employee_id", required = false) Long employee_id, #RequestBody Assignment a) {
Long yourId = employee_id != null ? employee_id : a.employee_id;
if (yourId == null) {
throw new RuntimeException("No id given"); // Not clean either but implemented by OP
} else {
Employee employeeById = employeeRepository.findById(yourId)
.orElseThrow(() -> new RuntimeException("Employee not found"));
a.setEmployee(employeeById);
assignmentRepository.addAssignment(a);
}
}
As the pathvariable is optionnal you try to get it first from url and then from your body object.
EDIT 2 : An Assignment might be created with no Employee_id
First case : You accept that an Assignment might have no Employee.
Simply change your relation from Assignment to Employee :
#OneToOne(optional = true)
#JoinColumn(name = "employee_id", nullable = true)
private Employee employee;
Second case : You want to create a new Employee first and then bind it to your assignement as an Assignment should always have an Employee
#PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
public void addEmployee(#PathVariable(value = "employee_id", required = false) Long employee_id, #RequestBody Assignment a) {
Long yourId = employee_id != null ? employee_id : a.employee_id;
Employee employeeById = yourId != null ?
employeeRepository.findById(yourId).orElseThrow(() -> new RuntimeException("Employee not found"))
: new Employee("title","staff",2L);
a.setEmployee(employeeById);
assignmentRepository.addAssignment(a);
}
Related
Hi I'm pretty new to Java and Spring Boot. I have an API which uses 3 entities:
#Entity
public class Account {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(updatable = false, nullable = false)
int id;
// Other fields
#Column(nullable = false)
String accountId;
#OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
#JsonBackReference
List<StockMarketTransaction> transactions;
#ManyToMany
#JsonBackReference
Set<StockMarketSubject> currentlyOwnedSubjects;
public int getId() {
return id;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public List<StockMarketTransaction> getTransactions() {
return transactions;
}
public void setTransactions(List<StockMarketTransaction> transactions) {
this.transactions = transactions;
}
public void addTransaction(StockMarketTransaction transaction){
this.transactions.add(transaction);
}
public Set<StockMarketSubject> getCurrentlyOwnedSubjects() {
return currentlyOwnedSubjects;
}
public void setCurrentlyOwnedSubjects(Set<StockMarketSubject> currentlyOwnedSubjects) {
this.currentlyOwnedSubjects = currentlyOwnedSubjects;
}
}
#Entity
public class StockMarketSubject{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
// Other fields
#OneToMany(mappedBy = "subject")
#JsonBackReference
List<StockMarketTransaction> transactions;
#ManyToMany
#JsonBackReference
Set<Account> holdingAccounts;
public int getId() {
return id;
}
public List<StockMarketTransaction> getTransactions() {
return transactions;
}
public void setTransactions(List<StockMarketTransaction> transactions) {
this.transactions = transactions;
}
public void addTransaction(StockMarketTransaction transaction){
this.transactions.add(transaction);
}
public Set<Account> getHoldingAccounts() {
return holdingAccounts;
}
public void setHoldingAccounts(Set<Account> holdingAccounts) {
this.holdingAccounts = holdingAccounts;
}
}
#Entity
public class StockMarketTransaction{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
// Other fields
#ManyToOne
#JsonManagedReference
StockMarketSubject subject;
#ManyToOne(cascade = CascadeType.ALL)
#JsonManagedReference
Account account;
public Long getId() {
return id;
}
public StockMarketSubject getSubject() {
return subject;
}
public void setSubject(StockMarketSubject subject) {
this.subject = subject;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
I'm also using DTO to transfer data between service layer (fetch/create/update) and controllers. GET endpoints return DTO structure with data and POST endpoints use DTO as #RequestBody in order to capture user data sent via request.
For Transaction entity I use this DTO with MapStruct Mapper:
public class StockMarketTransactionDTO {
#Schema(accessMode = Schema.AccessMode.READ_ONLY)
Long id;
// Other fields
#NotEmpty
#PositiveOrZero
int subjectId;
#NotEmpty
#PositiveOrZero
int accountId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getSubjectId() {
return subjectId;
}
public void setSubjectId(int subjectId) {
this.subjectId = subjectId;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
public StockMarketTransactionDTO(){}
}
#Mapper
public interface StockMarketTransactionMapper {
StockMarketTransactionMapper INSTANCE = Mappers.getMapper(StockMarketTransactionMapper.class);
#Mapping(source = "subject.id", target = "subjectId")
#Mapping(source = "account.id", target = "accountId")
StockMarketTransactionDTO stockMarketTransactionToStockMarketTransactionDTO(StockMarketTransaction transaction);
#InheritInverseConfiguration
StockMarketTransaction stockMarketTransactionDTOToStockMarketTransaction(StockMarketTransactionDTO dto);
}
Insted of exchanging whole objects related to transaction I want to only attach their ID (PK) to DTO. Now when I use this mapper to create transaction DTO from entity and return it with response it works perfectly fine. It gives users a valid ID of related subject and account. But the issue I have is creating entity from DTO filled with user data. With this payload:
{
"transactionDate": "2022-12-13T17:15:47.023Z",
"pricePerOne": 20,
"volume": 20,
"operationType": "BUY",
"description": {
"advantages": "string",
"disadvantages": "string",
"reason": "string"
}, // Other fields
"subjectId": 1,
"accountId": 1
}
I get internal error:
org.hibernate.PropertyValueException: not-null property references a null or transient value : com.rcbg.afku.investmentdiary.brokeraccounts.entities.Account.accountId
I tried find any efficient and proper way to map object like this with MapStruct but I failed.
Is there any possibility to handle this with #Mapping annotation, or should I create my own implementation of mapping method?
Im getting the following error:
{"timestamp":1535929757444,"status":500,"error":"Internal Server Error","exception":"org.springframework.dao.DataIntegrityViolationException","message":"could not execute statement; SQL [n/a]; constraint [\"PRIMARY KEY ON PUBLIC.WT_TASK(TASK_ID)\"; SQL statement:\ninsert into wt_task (exercise_id, task_id) values (?, ?) [23505-196]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement","path":"/api/word-transformation/new"}
I was able to create a service to fetch JSON from the database but I cant manage to upload them.
This is my service:
public WordTransformationExercise save(WordTransformationExerciseRequest wtRequest) {
WordTransformationExercise wordTransformation = new WordTransformationExercise();
wordTransformation.setAuthorId(wtRequest.getAuthor_id());
List<WordTransformationTaskRequest> testP = wtRequest.getwt_task();
List<WordTransformation> thisIsIt = new ArrayList<WordTransformation>();
for(WordTransformationTaskRequest task : testP) {
WordTransformation send = new WordTransformation();
send.setBody(task.getBody());
send.setResult(task.getResult());
send.setWord(task.getWord());
send.setWordAtIndex(task.getWord_at_index());
thisIsIt.add(send);
}
wordTransformation.setwt_task(thisIsIt);
this.wtRepository.save(wordTransformation);
return wordTransformation;
}
This is my Entity:
#Entity
#Table(name = "wt_exercise")
public class WordTransformationExercise implements Serializable {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "author_id")
private Long authorId;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "wt_task",
joinColumns = #JoinColumn(name = "exercise_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "task_id", referencedColumnName = "task_id"))
private List<WordTransformation> wt_task;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAuthorId() {
return authorId;
}
public void setAuthorId(Long authorId) {
this.authorId = authorId;
}
public void setwt_task(List<WordTransformation> list) {
this.wt_task = list;
}
public Collection<?> getwt_task() {
return this.wt_task;
}
}
This is Task entity:
#Entity
#Table(name = "wt_task")
public class WordTransformation implements Serializable {
#Id
#Column(name = "task_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long task_id;
#Column(name = "body")
private String body;
#Column(name = "result")
private String result;
#Column(name = "word")
private String word;
#Column(name = "word_at_index")
private Integer wordAtIndex;
#Column(name = "exercise_id")
private Long exercise_id;
public void setExercise_id(Long exercise_id) {
this.exercise_id = exercise_id;
}
public Long getExercise_id() {
return exercise_id;
}
public void setId(Long task_id) {
this.task_id = task_id;
}
public Long getId() {
return task_id;
}
public void setBody(String body) {
this.body = body;
}
public String getBody() {
return body;
}
public void setResult(String result) {
this.result = result;
}
public String getResult() {
return result;
}
public void setWord(String word) {
this.word = word;
}
public String getWord() {
return word;
}
public void setWordAtIndex(Integer wordAtIndex) {
this.wordAtIndex = wordAtIndex;
}
public Integer getWordAtIndex() {
return wordAtIndex;
}
}
My API is returning 'id' and 'authorId' fine when I set wt_task to null
This is an example of my sql:
INSERT INTO wt_exercise (id, author_id) VALUES (2, 2);
INSERT INTO wt_task (body, result, word, word_at_index, exercise_id, task_id) VALUES ('please start ', 'running', 'run', 13, 2, 2);
It depends on what you are trying to do.
If you are trying to update an existing entity, you should retrieve it from your repository and set the values instead of creating a new object and trying to save it with an existing key.
If you are trying to create something new then don't set the key at all.
SOLVED
But the real problem wasn't hibernate, it was mainly me and second Netbeans.
I was making a post, and saving my data. But I was making a duplicate post in js, and Netbeans won't fire breakpoints twice (and I don't really know why). So, for me, it was making one post and just one insert. But no, two posts, and two inserts.
Sorry for losing your time :/
I'm new to Hibernate, so I'm having some problems, maybe it's just a silly one, I don't really know.
I'm trying to insert an object to database with a #ManyToOne relationship, but Hibernate is duplicating it when I persist and commit the transaction. This is my code.
User Post Class
#Entity
#Table(name = "USERPOST", schema = "ADMIN1")
public class UserPost implements java.io.Serializable {
private int iduserpost;
private String detail;
private User user;
public UserPost() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "IDUSERPOST", unique = true, nullable = false)
public int getIduserpost() {
return this.iduserpost;
}
public void setIduserpost(int iduserpost) {
this.iduserpost = iduserpost;
}
#Column(name = "DETAIL", nullable = false)
public String getDetail() {
return this.detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
#ManyToOne
#JoinColumn(name = "IDUSER")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
User Class
#Entity
#Table(name = "USER", schema = "ADMIN1")
public class User implements java.io.Serializable {
private int iduser;
private String name;
private String email;
private Set<UserPost> posts;
public User() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "IDUSER", unique = true, nullable = false)
public int getIduser() {
return this.iduser;
}
public void setIduser(int iduser) {
this.iduser = iduser;
}
#Column(name = "NAME", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "EMAIL", nullable = false)
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
#OneToMany(mappedBy = "user")
public Set<UserPost> getPosts() {
return posts;
}
public void setPosts(Set<UserPost> posts) {
this.posts = posts;
}
}
Insert Method on Manager
public void Insert(Object data) {
Session session = null;
try {
session = hibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.persist(data);
session.getTransaction().commit();
} catch (Exception e) {
System.err.println(e.getMessage());
throw e;
} finally {
if (session.isOpen()) {
session.close();
}
}
}
Insert on Servlet
FeedManager manager = new FeedManager();
UserPost post = new UserPost();
post.setDetail(text);
User usrPesist = (User) manager.GetById(User.class, idUser);
post.setUser(usrPesist);
manager.Insert(post);
The result I'm getting is TWO UserPosts being inserted to database, when what I want is just one.
Is there something wrong?
Since you have defined as private Set<UserPost> posts; in User Class,
implement equals and hashcode methods in UserPost class , in that way you ensure that since it is a Set it wont add duplicates
But this is not a optimal way though.
I think this is problem with you id generation strategy in your user class. Just try by setting id manually in user class object it will work.
Try changing your code with this :
#org.hibernate.annotations.Cascade( {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
#OneToMany(mappedBy = "user")
#JoinColumn(name = "IDUSER")
public Set<UserPost> getPosts() {
return posts;
}
I'm using Jersey + spring + hibernate4.17 to develop api system; The problem is if the cleaFields is called twice at same time, the 2nd call will throw an exception as below,
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.checkRowCounts(BatchingBatch.java:133)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:149)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:162)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:357)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
The clearFields method in the Controller,
#Transactional(isolation=Isolation.REPEATABLE_READ)
public void clearFields(Integer userId) {
User user = this.userDao.get(userId);
user.getFields().clear();
userDao.flush(); //call the current session.flush(); this line can throw exception.
}
User Entity class
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id", unique = true, nullable = false)
private int userId;
#OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, targetEntity = UserProfile.class, fetch = FetchType.LAZY, orphanRemoval=true)
#OrderBy("id")
private List<UserProfile> fields = new ArrayList<UserProfile>();
public User() {
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public List<UserProfile> getFields() {
return fields;
}
public void setFields(List<UserProfile> fields) {
this.fields = fields;
}
}
UserProfile class,
#Entity
#Table(name="user_profiles")
public class UserProfile implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="field_name")
private String fieldName;
#ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
#JoinColumn(name="user_id")
private User user;
private String value;
public UserProfile() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFieldName() {
return this.fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
I did some research, the root cause is if the 2nd calling get some fields, and before delete them, the 1st calling already delete all fields from database.
In another word, the 2nd calling try to delete some records which already were deleted by others.
How can I solve the problem?
I have following classes in my project.
Employee class
#XmlRootElement
#Entity
#Table(name = "emp", catalog = "emps")
public class Employee implements java.io.Serializable {
//other entity variables
private Set<Title> titles = new HashSet<Title>(0);
#XmlTransient
#OneToMany(targetEntity = Title.class, fetch = FetchType.EAGER, mappedBy = "employee", cascade=CascadeType.ALL)
public Set<Title> getTitles() {
return this.titles;
}
public void setTitles(Set<Title> titles) {
this.titles = titles;
}
}
Title
#Entity
#Table(name = "titles", catalog = "emps")
public class Title implements java.io.Serializable {
private TitleId id;
private Employee employee;
private Date fromDate;
private Date toDate;
public Title() {
}
public Title(TitleId id, Employee employee) {
this.id = id;
this.employee = employee;
}
public Title(TitleId id, Employee employee, Date toDate) {
this.id = id;
this.employee = employee;
this.toDate = toDate;
}
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "empNo", column = #Column(name = "emp_no", nullable = false)),
#AttributeOverride(name = "title", column = #Column(name = "title", nullable = false, length = 50)),
#AttributeOverride(name = "fromDate", column = #Column(name = "from_date", nullable = false, length = 10)) })
public TitleId getId() {
return this.id;
}
public void setId(TitleId id) {
this.id = id;
}
//rest of the code
}
Title Id
#Embeddable
public class TitleId implements java.io.Serializable {
private int empNo;
private String title;
private Date fromDate;
public TitleId() {
}
public TitleId(int empNo, String title, Date fromDate) {
this.empNo = empNo;
this.title = title;
this.fromDate = fromDate;
}
#Column(name = "emp_no", nullable = false)
public int getEmpNo() {
return this.empNo;
}
public void setEmpNo(int empNo) {
this.empNo = empNo;
}
#Column(name = "title", nullable = false, length = 50)
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "from_date", nullable = false, length = 10)
public Date getFromDate() {
return this.fromDate;
}
public void setFromDate(Date fromDate) {
this.fromDate = fromDate;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof TitleId))
return false;
TitleId castOther = (TitleId) other;
return (this.getEmpNo() == castOther.getEmpNo())
&& ((this.getTitle() == castOther.getTitle()) || (this
.getTitle() != null && castOther.getTitle() != null && this
.getTitle().equals(castOther.getTitle())))
&& ((this.getFromDate() == castOther.getFromDate()) || (this
.getFromDate() != null
&& castOther.getFromDate() != null && this
.getFromDate().equals(castOther.getFromDate())));
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getEmpNo();
result = 37 * result
+ (getTitle() == null ? 0 : this.getTitle().hashCode());
result = 37 * result
+ (getFromDate() == null ? 0 : this.getFromDate().hashCode());
return result;
}
}
I need to create a criteria to find the first name, last name and title of the users. The first name and last names are working fine in my criteria. The following code shows how I create my criteria for titles. "jobTitle" is a parameter that I'm passing to it.
Criteria employeeSearchCriteria = getSession().createCriteria(Employee.class);
employeeSearchCriteria.setFirstResult(0);
employeeSearchCriteria.setMaxResults(6);
employeeSearchCriteria.createAlias("titles.TitleId", "titleId");
employeeSearchCriteria.add(Restrictions.eq("titleId.title", jobTitle));
When I run the code it throws an Query Exception saying org.hibernate.QueryException: could not resolve property: TitleId of: Title. Can anyone help me in this matter?
I'm guessing here, but try changing in class Title the getter method name from getId() to getTitleId().
Otherwise, I can just say that all of the examples I saw that uses #EmbeddedId show how to do it on the field itself, rather than on the getter as you did. So you might just as well try also to annotate the field (although Hibernate recommends not to mix method and field mapping annotations).