Spring JpaRepository save causes 100s of selects to be generated - jpa

Im getting very strange error when I call save on a JpaRepository.
The code seems trivial so i can only think its something to do with configuration.
Basically I call a findBy method on the repository, this returns a list of dao objects exactly as expected, I go through this list setting a timestamp then calling save() on each dao, as soon as the first save is called the log is filled with hundreds of identical select statements, selecting on the dao I'm just trying to save until eventually there is a stack overflow.
What could cause this ???
(note originally I called saveAll() on the list of dao objects - this, unsurprisingly has the same error )
public void triggerDeletion() {
ZonedDateTime expiryDate = ZonedDateTime.now().minus(daysAfterExpiry);
// Get list of conversations to delete
List<ConversationDao> conversationDaoList = conversationDatabaseService.retrieveExpiredConversations(expiryDate);
// Mark each conversation as deleted by setting its deletion timestamp to now.
conversationDaoList.stream().forEach(conversation->delete(conversation));
}
public void delete(ConversationDao conversationDao){
conversationDao.setDeletionTimestamp(new Timestamp(System.currentTimeMillis()));
conversationDatabaseService.save( conversationDao ); <------ This generates 100s of select statements.
}
...
// ConversationDatabaseService Interface
////////////////////////////////////////
public interface ConversationDatabaseService {
void save(ConversationDao conversationDao);
}
...
// Conversation DatabaseService Class
/////////////////////////////////////
#Service
public class ConversationDatabaseServiceImpl implements ConversationDatabaseService {
private final ConversationRepository conversationRepository;
public void save(ConversationDao conversationDao) {
conversationRepository.saveAndFlush(conversationDao); // Just save has also been tried.
}
}
...
// ConversationRepository interface
///////////////////////////////////
public interface ConversationRepository extends JpaRepository<ConversationDao, String> {
List<ConversationDao> findByExpiryDateLessThanAndDeletionTimestampIsNull(Timestamp expiryDate);
}
...
// ConversationDao
//////////////////////////////////
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
#Entity
#Table(name = "DOCX_CONVERSATION")
public class ConversationDao {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2",
strategy = "uuid2")
#Column(name = "CONVERSATION_ID",
columnDefinition = "char")
private String conversationId;
#Column(name = "PROCESS_CODE")
private String processCode;
#Column(name = "PROFILE_ID",
columnDefinition = "char")
private String profileId;
#Column(name = "REMINDER_EMAIL_SENT",
columnDefinition = "char")
private String reminderEmailSent;
#Column(name = "EXPIRY_DATE")
private Date expiryDate;
#Column(name = "DELETION_TIMESTAMP")
private Timestamp deletionTimestamp;
#Column(name = "LAST_LOGIN_TIMESTAMP")
private Timestamp lastLoginTimestamp;
#Column(name = "CREATED_USER_ID",
columnDefinition = "char")
private String colleagueId;
#Column(name = "CREATED_TIMESTAMP",
updatable = false)
#CreationTimestamp
private Timestamp createdTimestamp;
#Column(name = "LAST_UPDATED_USER_ID",
columnDefinition = "char")
private String lastUpdatedUserId;
#Column(name = "LAST_UPDATED_TIMESTAMP")
#UpdateTimestamp
private Timestamp lastUpdatedTimestamp;
#OneToMany(mappedBy = "conversation",
cascade = CascadeType.ALL)
private Set<MessageDetailDao> messageDetailDaoSet = new HashSet<>();
#OneToMany(mappedBy = "fileDetailId.conversation",
cascade = CascadeType.ALL)
private Set<FileDetailDao> fileDetailDaoSet = new HashSet<>();
#OneToMany(mappedBy = "conversation",
cascade = CascadeType.ALL)
private Set<ParameterDao> parameterDaoSet = new HashSet<>();
#OneToMany(mappedBy = "conversation",
cascade = CascadeType.ALL)
private Set<NotificationDao> notificationDaoSet = new HashSet<>();
public ConversationDao() {
}
public ConversationDao(String processCode, Date expiryDate,
String colleagueId, String lastUpdatedUserId) {
this.processCode = processCode;
this.reminderEmailSent = "N";
this.expiryDate = expiryDate;
this.colleagueId = colleagueId;
this.lastUpdatedUserId = lastUpdatedUserId;
}
public String getConversationId() {
return conversationId;
}
public void setConversationId(String conversationId) {
this.conversationId = conversationId;
}
public String getProcessCode() {
return processCode;
}
public void setProcessCode(String processCode) {
this.processCode = processCode;
}
public String getProfileId() {
return profileId;
}
public void setProfileId(String profileId) {
this.profileId = profileId;
}
public String getReminderEmailSent() {
return reminderEmailSent;
}
public void setReminderEmailSent(String reminderEmailSent) {
this.reminderEmailSent = reminderEmailSent;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
public Timestamp getDeletionTimestamp() {
return deletionTimestamp;
}
public void setDeletionTimestamp(Timestamp deletionTimestamp) {
this.deletionTimestamp = deletionTimestamp;
}
public Timestamp getLastLoginTimestamp() {
return lastLoginTimestamp;
}
public void setLastLoginTimestamp(Timestamp lastLoginTimestamp) {
this.lastLoginTimestamp = lastLoginTimestamp;
}
public String getColleagueId() {
return colleagueId.trim();
}
public void setColleagueId(String colleagueId) {
this.colleagueId = colleagueId;
}
public Timestamp getCreatedTimestamp() {
return createdTimestamp;
}
public void setCreatedTimestamp(Timestamp createdTimestamp) {
this.createdTimestamp = createdTimestamp;
}
public String getLastUpdatedUserId() {
return lastUpdatedUserId;
}
public void setLastUpdatedUserId(String lastUpdatedUserId) {
this.lastUpdatedUserId = lastUpdatedUserId;
}
public Timestamp getLastUpdatedTimestamp() {
return lastUpdatedTimestamp;
}
public void setLastUpdatedTimestamp(Timestamp lastUpdatedTimestamp) {
this.lastUpdatedTimestamp = lastUpdatedTimestamp;
}
public void addMessageDetailDao(MessageDetailDao messageDetailDao) {
messageDetailDaoSet.add(messageDetailDao);
messageDetailDao.setConversation(this);
}
public Set<MessageDetailDao> getMessageDetailDao() {
return messageDetailDaoSet;
}
public void addFileDetailDao(FileDetailDao fileDetailDao) {
fileDetailDaoSet.add(fileDetailDao);
fileDetailDao.getId().setConversation(this);
}
public Set<FileDetailDao> getFileDetailDao() {
return fileDetailDaoSet;
}
public void addParameterDao(ParameterDao parameterDao) {
parameterDaoSet.add(parameterDao);
parameterDao.setConversation(this);
}
public Set<ParameterDao> getParameterDao() {
return parameterDaoSet;
}
public void addNotificationDao(NotificationDao notificationDao) {
notificationDaoSet.add(notificationDao);
notificationDao.setConversation(this);
}
public Set<NotificationDao> getNotificationDao() {
return notificationDaoSet;
}
}
}
This generates these same select statements 100s of times before blowing the stack :-
1TS="20190411.075004.028" 4MSG="binding parameter [1] as [VARCHAR] - [6df49d6f-216b-460d-9282-2d25c098f9fe]" 1EVC="TRACE" 2CLS="BasicBinder"
1TS="20190411.075004.065" 4MSG="extracted value ([convers16_10_0_] : [VARCHAR]) - [6df49d6f-216b-460d-9282-2d25c098f9fe]" 1EVC="TRACE" 2CLS="BasicExtractor"
1TS="20190411.075004.069" 4MSG="extracted value ([file_met1_10_0_] : [VARCHAR]) - [4E90FD20-FC59-41B8-BF8E-88B7D682A87C]" 1EVC="TRACE" 2CLS="BasicExtractor"
1TS="20190411.075004.074" 4MSG="select conversati0_.conversation_id as conversa1_5_1_, conversati0_.created_user_id as created_2_5_1_, conversati0_.created_timestamp as created_3_5_1_, conversati0_.deletion_timestamp as deletion4_5_1_, conversati0_.expiry_date as expiry_d5_5_1_, conversati0_.last_login_timestamp as last_log6_5_1_, conversati0_.last_updated_timestamp as last_upd7_5_1_, conversati0_.last_updated_user_id as last_upd8_5_1_, conversati0_.process_code as process_9_5_1_, conversati0_.profile_id as profile10_5_1_, conversati0_.reminder_email_sent as reminde11_5_1_, filedetail1_.conversation_id as convers16_10_3_, filedetail1_.file_metadata_id as file_met1_10_3_, filedetail1_.conversation_id as convers16_10_0_, filedetail1_.file_metadata_id as file_met1_10_0_, filedetail1_.application_id as applicat2_10_0_, filedetail1_.case_id as case_id3_10_0_, filedetail1_.created_user_id as created_4_10_0_, filedetail1_.content_type as content_5_10_0_, filedetail1_.created_by as created_6_10_0_, filedetail1_.created_timestamp as created_7_10_0_, filedetail1_.document_code as document8_10_0_, filedetail1_.document_owner as document9_10_0_, filedetail1_.document_repository_state as documen10_10_0_, filedetail1_.file_name as file_na11_10_0_, filedetail1_.file_size_bytes as file_si12_10_0_, filedetail1_.file_state as file_st13_10_0_, filedetail1_.file_version as file_ve14_10_0_, filedetail1_.updated_by as updated15_10_0_ from docx_conversation conversati0_ left outer join docx_file_detail filedetail1_ on conversati0_.conversation_id=filedetail1_.conversation_id where conversati0_.conversation_id=?" 1EVC="DEBUG" 2CLS="SQL"
What is going on ??
Some more information, the cause is definitely connected to this part of the dao :-
#OneToMany(mappedBy = "fileDetailId.conversation",cascade = CascadeType.ALL)
private Set<FileDetailDao> fileDetailDaoSet = new HashSet<>();
The FileDetailDao contains an embedded reference to a FileDetailId
#EmbeddedId
private FileDetailId fileDetailId;
And this FileDetailId contains a reference to the conversationId of the join :-
#Embeddable
public class FileDetailId implements Serializable {
#Column(name = "FILE_METADATA_ID", columnDefinition = "char")
private String fileMetadataId;
#ManyToOne
#JoinColumn(name = "CONVERSATION_ID")
private ConversationDao conversation;
//etc
}

Im not sure why but if I change the cascade type to REMOVE it works ok....
#OneToMany(mappedBy = "fileDetailId.conversation",cascade = CascadeType.REMOVE)
private Set<FileDetailDao> fileDetailDaoSet = new HashSet<>();

Related

JPA won't save an entity correctly unless the references to other entities are set

If I save this entity using JPA repository with a new defaultAssetId, it will only update the defaultAsssetId to the new value if I set defaultAsset as well. I want to be able to save without setting defaultAsset.
Same problem applies to taskType and assetRole.
package au.com.polonious.conf.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
#Entity
public class TaskTypeAssetRole implements Serializable {
#GenericGenerator(name="tasktypeassetroleidseq",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
#Parameter(name = "sequence_name", value = "tasktypeassetroleidseq"),
#Parameter(name = "initial_value", value = "1"),
#Parameter(name = "increment_size", value = "1")
})
#Id
#GeneratedValue(generator = "tasktypeassetroleidseq")
private Long id;
#Column(insertable = false, updatable=false)
private Long taskTypeId;
#Fetch(FetchMode.JOIN)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="tasktypeid")
private TaskType taskType;
#Column(insertable = false, updatable=false)
private Long assetRoleId;
#Fetch(FetchMode.JOIN)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="assetRoleId")
private Role assetRole;
#Column(insertable = false, updatable=false)
private Long defaultAssetId;
#Fetch(FetchMode.JOIN)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="defaultassetid")
private Asset defaultAsset;
private Date startDate;
private Date endDate;
private String notes;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTaskTypeId() {
return taskTypeId;
}
public void setTaskTypeId(Long taskTypeId) {
this.taskTypeId = taskTypeId;
}
public TaskType getTaskType() {
return taskType;
}
public void setTaskType(TaskType taskType) {
this.taskType = taskType;
}
public Long getAssetRoleId() {
return assetRoleId;
}
public void setAssetRoleId(Long assetRoleId) {
this.assetRoleId = assetRoleId;
}
public Role getAssetRole() {
return assetRole;
}
public void setAssetRole(Role assetRole) {
this.assetRole = assetRole;
}
public Long getDefaultAssetId() {
return defaultAssetId;
}
public void setDefaultAssetId(Long defaultAssetId) {
this.defaultAssetId = defaultAssetId;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
I tried saving a taskTypeAssetRole with a new defaultAssedId without setting defaultAsset and I expected the defaultAssedId for that entry in the database to be updated.
What ended up happening was defaultAssetId didn't change although everything else in the entry did update successfully and there were no errors.
Your mapping is inherently broken. The column defaultassetiId is mapped to two different values: the field defaultAssetId and to the id of defaultAsset.
You should remove the defaultAssetId because this construct might break on any update of your JPA provider.
You can use references instead of full entities to set the reference values without loading entities from the database. See https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html#getReferenceById-ID-
If you don't follow this advice you should remove updatable=false if you want to update a field.

Spring Data JPA. Parent table data is not getting rolled back when exception occurred while inserting record in child table

I have 2 tables one to many relationship between Employee and Department table, Employee table are having column Id as PK, Name and Sal whereas Department table having column Dept_ID,Dept_Name & Dept_Loc and primary key is (Dept_ID,Dept_Name) i.e composite key and Dept_ID is foreign key ref from Employee table's Id column. The issue is when I save record in parent table i.e Employee it get saved but if in case I get exception while inserting record for child table i.e Department table,,data is not getting rolled back for EMployee table. Please help I m struggling and I am attaching my code.
public class GlEmployee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_seq")
#Column(name = "EMP_ID")
private long empId;
#Column(name = "EMP_CITY")
private String empCity;
#Column(name = "EMP_NAME")
private String empName;
#Column(name = "EMP_SALARY")
private BigDecimal empSalary;
// bi-directional many-to-one association to EmpDepartment
#OneToMany(mappedBy = "glEmployee",cascade = CascadeType.ALL)
private List<EmpDepartment> empDepartments = new ArrayList<>();
public GlEmployee() {
}
public long getEmpId() {
return this.empId;
}
public void setEmpId(long empId) {
this.empId = empId;
}
public String getEmpCity() {
return this.empCity;
}
public void setEmpCity(String empCity) {
this.empCity = empCity;
}
public String getEmpName() {
return this.empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public BigDecimal getEmpSalary() {
return this.empSalary;
}
public void setEmpSalary(BigDecimal empSalary) {
this.empSalary = empSalary;
}
public List<EmpDepartment> getEmpDepartments() {
return this.empDepartments;
}
public void setEmpDepartments(List<EmpDepartment> empDepartments) {
this.empDepartments = empDepartments;
}
public EmpDepartment addEmpDepartment(EmpDepartment empDepartment) {
getEmpDepartments().add(empDepartment);
empDepartment.setGlEmployee(this);
return empDepartment;
}
public EmpDepartment removeEmpDepartment(EmpDepartment empDepartment) {
getEmpDepartments().remove(empDepartment);
empDepartment.setGlEmployee(null);
return empDepartment;
}
}
#Entity
#Table(name = "EMP_DEPARTMENT")
public class EmpDepartment implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private EmpDepartmentPK id;
#Column(name = "DEP_LOC")
private String depLoc;
public EmpDepartment(EmpDepartment id, String dep) {
}
// bi-directional many-to-one association to GlEmployee
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "DEP_ID", insertable = false, updatable = false)
private GlEmployee glEmployee;
public EmpDepartment() {
}
public EmpDepartmentPK getId() {
return this.id;
}
public void setId(GlEmployee glEmployee, String deptName) {
EmpDepartmentPK empDepartment = new
EmpDepartmentPK(glEmployee.getEmpId(), deptName);
this.id = empDepartment;
}
public String getDepLoc() {
return this.depLoc;
}
public void setDepLoc(String depLoc) {
this.depLoc = depLoc;
}
public GlEmployee getGlEmployee() {
return this.glEmployee;
}
public void setGlEmployee(GlEmployee glEmployee) {
this.glEmployee = glEmployee;
}
}
#Embeddable
public class EmpDepartmentPK implements Serializable {
// default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(name = "DEP_ID")
private long depId;
#Column(name = "DEP_NAME")
private String depName;
public EmpDepartmentPK() {
}
public EmpDepartmentPK(long depId, String depName) {
super();
this.depId = depId;
this.depName = depName;
}
public long getDepId() {
return this.depId;
}
public void setDepId(long depId) {
this.depId = depId;
}
public String getDepName() {
return this.depName;
}
public void setDepName(String depName) {
this.depName = depName;
}
#Service
public class EmployeeService {
#Autowired
private EmployeeRepository employeeRepository;
#Transactional
public void createEmp() {
GlEmployee employee = new GlEmployee();
employee.setEmpCity("Pune");
employee.setEmpName("Ankush");
employee.setEmpSalary(new BigDecimal(200));
employeeRepository.save(employee);
EmpDepartment department = new EmpDepartment();
department.setId(employee, "ME");
department.setDepLoc(null);
department.setGlEmployee(employee);
employee.addEmpDepartment(department);
employeeRepository.save(employee);
}
}

Add data to database adding data to join tables

I'm working in a project and I'm looking to add data to the database, to two join tables.
My parent:
package entity;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the artiste database table.
*
*/
#Entity
#NamedQuery(name="Artiste.findAll", query="SELECT a FROM Artiste a")
public class Artiste implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id_artiste")
private int idArtiste;
#Column(name="a_category")
private String aCategory;
#Column(name="a_name")
private String aName;
private String date;
//bi-directional many-to-one association to Seat
#ManyToOne
#JoinColumn(name="id_seat")
private Seat seat;
public Artiste() {
}
public int getIdArtiste() {
return this.idArtiste;
}
public void setIdArtiste(int idArtiste) {
this.idArtiste = idArtiste;
}
public String getACategory() {
return this.aCategory;
}
public void setACategory(String aCategory) {
this.aCategory = aCategory;
}
public String getAName() {
return this.aName;
}
public void setAName(String aName) {
this.aName = aName;
}
public String getDate() {
return this.date;
}
public void setDate(String date) {
this.date = date;
}
public Seat getSeat() {
return this.seat;
}
public void setSeat(Seat seat) {
this.seat = seat;
}
}
My child:
package entity;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the seat database table.
*
*/
#Entity
#NamedQuery(name="Seat.findAll", query="SELECT s FROM Seat s")
public class Seat implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id_seat")
private int idSeat;
private String seat_CA;
private String seat_CB;
private String seat_CC;
private String seat_CD;
//bi-directional many-to-one association to Artiste
#OneToMany(mappedBy="seat")
private List<Artiste> artistes;
public Seat() {
}
public int getIdSeat() {
return this.idSeat;
}
public void setIdSeat(int idSeat) {
this.idSeat = idSeat;
}
public String getSeat_CA() {
return this.seat_CA;
}
public void setSeat_CA(String seat_CA) {
this.seat_CA = seat_CA;
}
public String getSeat_CB() {
return this.seat_CB;
}
public void setSeat_CB(String seat_CB) {
this.seat_CB = seat_CB;
}
public String getSeat_CC() {
return this.seat_CC;
}
public void setSeat_CC(String seat_CC) {
this.seat_CC = seat_CC;
}
public String getSeat_CD() {
return this.seat_CD;
}
public void setSeat_CD(String seat_CD) {
this.seat_CD = seat_CD;
}
public List<Artiste> getArtistes() {
return this.artistes;
}
public void setArtistes(List<Artiste> artistes) {
this.artistes = artistes;
}
public Artiste addArtiste(Artiste artiste) {
getArtistes().add(artiste);
artiste.setSeat(this);
return artiste;
}
public Artiste removeArtiste(Artiste artiste) {
getArtistes().remove(artiste);
artiste.setSeat(null);
return artiste;
}
}
My client:
Artiste a= new Artiste();
Seat b = new Seat();
b.setSeat_CA(request.getParameter("w"));
b.setSeat_CB(request.getParameter("x"));
b.setSeat_CD(request.getParameter("y"));
b.setSeat_CC(request.getParameter("z"));
a.setIdArtiste(b.getIdSeat());
seatFacade.create(b);
a.setAName(request.getParameter("a_name"));
a.setACategory(request.getParameter("a_category"));
a.setDate(request.getParameter("date"));
artisteFacade.create(a);
And I create the FACADE for each one.
Now I can add data but i need also the program add the FOREIGN KEY.
You don't need to get the foreign key, JPA is do every thing, so you should just make it in the right way, so you entities should look like this:
Artiste Entity
#ManyToOne
#JoinColumn(name="id_seat")
private Seat seat;
Seat Entity
#OneToMany(mappedBy="seat", cascade = CascadeType.ALL)
private List<Artiste> artistes = new ArrayList<>();
Your code should look like this:
Artiste a= new Artiste();
Seat b = new Seat();
b.setSeat_CA(request.getParameter("w"));
b.setSeat_CB(request.getParameter("x"));
b.setSeat_CD(request.getParameter("y"));
b.setSeat_CC(request.getParameter("z"));
a.setAName(request.getParameter("a_name"));
a.setACategory(request.getParameter("a_category"));
a.setDate(request.getParameter("date"));
//add this the Article to the list of Seat like this.
b.getArtistes().add(a);
//a.setIdArtiste(b.getIdSeat()); you don't need this
//artisteFacade.create(a); you dont need this also
//set the Seal to your article
a.setSeat(b);
seatFacade.create(b);
So when you persist the Seat the list of articles will persist automaticlly.
This will help you.
You can learn more here : JPA #ManyToOne with CascadeType.ALL

jpa named query using foreign key is not working

MY Entity class
#Entity
#Table(catalog = "", schema = "MYIS")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Answers.findAll", query = "SELECT a FROM Answers a"),
#NamedQuery(name = "Answers.findByAid", query = "SELECT a FROM Answers a WHERE a.aid = :aid"),
#NamedQuery(name ="Anaswers.findByqid", query ="SELECT a FROM Answers a WHERE a.answerQid.qid = :x"),
#NamedQuery(name = "Answers.findByAnsValue", query = "SELECT a FROM Answers a WHERE a.ansValue = :ansValue"),
#NamedQuery(name = "Answers.findByAnsDate", query = "SELECT a FROM Answers a WHERE a.ansDate = :ansDate")})
public class Answers implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(nullable = false)
private Integer aid;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 4000)
#Column(name = "ANS_VALUE", nullable = false, length = 4000)
private String ansValue;
#Basic(optional = false)
#NotNull
#Column(name = "ANS_DATE", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
private Date ansDate;
#JoinColumn(name = "A_USERID", referencedColumnName = "USERID", nullable = false)
#ManyToOne(optional = false)
private Users aUserid;
#JoinColumn(name = "ANSWER_QID", referencedColumnName = "QID", nullable = false)
#ManyToOne(optional = false)
private Questions answerQid;
#JoinColumn(name = "A_GROUPID", referencedColumnName = "GID", nullable = false)
#ManyToOne(optional = false)
private Groups aGroupid;
public Answers() {
}
public Answers(Integer aid) {
this.aid = aid;
}
public Answers(Integer aid, String ansValue, Date ansDate) {
this.aid = aid;
this.ansValue = ansValue;
this.ansDate = ansDate;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAnsValue() {
return ansValue;
}
public void setAnsValue(String ansValue) {
this.ansValue = ansValue;
}
public Date getAnsDate() {
return ansDate;
}
public void setAnsDate(Date ansDate) {
this.ansDate = ansDate;
}
public Users getAUserid() {
return aUserid;
}
public void setAUserid(Users aUserid) {
this.aUserid = aUserid;
}
public Questions getAnswerQid() {
return answerQid;
}
public void setAnswerQid(Questions answerQid) {
this.answerQid = answerQid;
}
public Groups getAGroupid() {
return aGroupid;
}
public void setAGroupid(Groups aGroupid) {
this.aGroupid = aGroupid;
}
#Override
public int hashCode() {
int hash = 0;
hash += (aid != null ? aid.hashCode() : 0);
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 Answers)) {
return false;
}
Answers other = (Answers) object;
if ((this.aid == null && other.aid != null) || (this.aid != null && !this.aid.equals(other.aid))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.entity.Answers[ aid=" + aid + " ]";
}
}
MY SESSION FACADE
import com.entity.Answers;
import com.entity.Groups;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
*
* #author krishna teja
*/
#Stateless
public class AnswersFacade extends AbstractFacade<Answers> implements AnswersFacadeLocal {
#PersistenceContext(unitName = "My_communityPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public AnswersFacade() {
super(Answers.class);
}
public List<Answers> getdataByQid(Long qid){
Query query=em.createNamedQuery("Answers.findByqid");
query.setParameter(1, qid);
List<Answers> a =query.getResultList();
return a;
}
}
My managed bean
#PostConstruct
public void init(){
questions = questionsFacade.findAll();
ansList = answersFacade.getdataByQid(g);
}
I am getting following exception
at com.ejb.AnswersFacade.getdataByQid(AnswersFacade.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
I have created named query for the foreign key attribute answerQid and and created method in the sessionfacade and tried to access it in the managed bean the default methods work perfectly but my method for query is not working please help me
Looks like a simple typo. Named query is defined as Anaswers.findByqid, but used as Answers.findByqid.

JPA multi-entity relationship

How can I write the following relationship in JPA. I have 6 tables: Products, Features, Functions, Tasks, Permissions and Users. I need to be able to create a Product object model that contains a list of Features. Each Feature object model in the list will contain a list of Functions and each Function will contain a list of Tasks. I have no issue building each one of these entities and then relating them together but the problem comes in when I need to filter each entity by its relationship to the Permission table. I'm not sure this can be done. When I map the Permissions entity to each other entity, I seem to get a many-to-many join and too many values are returned. Any insight would be great.
Products
prod_id
user_id
Features
prod_id
feature_id
Functions
prod_id
feature_id
function_id
Tasks
prod_id
feature_id
function_id
task_id
Permissions
prod_id
feature_id
function_id
task_id
user_id
User
user_id
Here is my Permission entity class:
import java.io.Serializable;
import javax.persistence.*;
import static javax.persistence.CascadeType.ALL;
import java.math.BigDecimal;
#IdClass(menu.entity.PermissionKey.class)
#Entity
#Table(name="PERMISSIONS")
#NamedQuery(name = "findPermissionsByUserId",query = "SELECT p FROM Permission p WHERE p.userId = :userId")
public class Permission implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name="AUTH", length=1)
private String auth;
#Column(name="PERM_DESC", length=80)
private String permDesc;
#Id
#Column(name="COMPANY",
nullable = false,
insertable = false,
updatable = false,
length=2)
private String company;
#Id
#Column(name="USER_ID",
nullable = false,
insertable = false,
updatable = false,
length=30)
private String userId;
#Id
#Column(name="PROD_ID", precision=22)
private BigDecimal prodId;
#Id
#Column(name="FEATURE", precision=22)
private BigDecimal feature;
#Id
#Column(name="FUNC", precision=22)
private BigDecimal func;
#Id
#Column(name="TASK", precision=22)
private BigDecimal task;
//uni-directional one-to-one association to Product
#OneToOne(cascade=ALL, mappedBy="permission")
private Product productObj;
#OneToOne(cascade=ALL, mappedBy="permission")
private Feature featureObj;
#OneToOne(cascade=ALL, mappedBy="permission")
private Function functionObj;
#OneToOne(cascade=ALL, mappedBy="permission")
private Task taskObj;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name="USER_ID", referencedColumnName="USER_ID"),
#JoinColumn(name="COMPANY", referencedColumnName="COMPANY")
})
private User user;
public Permission() {
}
public String getAuth() {
return this.auth;
}
public void setAuth(String auth) {
this.auth = auth;
}
public String getCompany() {
return this.company;
}
public void setCompany(String company) {
this.company = company;
}
public String getPermDesc() {
return this.permDesc;
}
public void setPermDesc(String permDesc) {
this.permDesc = permDesc;
}
public String getUserId() {
return this.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public BigDecimal getProdId() {
return prodId;
}
public void setProdId(BigDecimal prodId) {
this.prodId = prodId;
}
public BigDecimal getFeature() {
return this.feature;
}
public void setFeature(BigDecimal feature) {
this.feature = feature;
}
public BigDecimal getFunc() {
return func;
}
public void setFunc(BigDecimal func) {
this.func = func;
}
public BigDecimal getTask() {
return task;
}
public void setTask(BigDecimal task) {
this.task = task;
}
public Product getProductObj() {
return this.productObj;
}
public void setProductObj(Product productObj) {
this.productObj = productObj;
}
public Feature getFeatureObj() {
return this.featureObj;
}
public void setFeatureObj(Feature featureObj) {
this.featureObj = featureObj;
}
public Function getFunctionObj() {
return this.functionObj;
}
public void setFunctionObj(Function functionObj) {
this.functionObj = functionObj;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
public Task getTaskObj() {
return this.taskObj;
}
public void setTaskObj(Task taskObj) {
this.taskObj = taskObj;
}
}