JPA JSF creating a new record doesn't update the page - jpa

The following p:dialog creates a new comment using:
<p:dialog id="buyDlg" widgetVar="buyDialog" modal="true" resizable="false" appendTo="#(body)"
header="#{myBundle.CreateCommentsTitle}" closeOnEscape="true" width="auto" height="auto">
<h:form id="buyCommentCreateForm">
<h:panelGroup id="buyDisplay">
<p:outputPanel id="buyCommentsPanel">
<p:row>
<p:column>
<p:editor id="commentText" value="#{commentsController.selected.commentText}" style="margin-bottom:10px"/>
</p:column>
</p:row>
</p:outputPanel>
<p:commandButton actionListener="#{commentsController.setBuyComment(pmMainController.selected.idPmMain, commentsController.selected.commentText)}" value="#{myBundle.Save}" update=":PmMainEditForm:display" oncomplete="handleSubmit(xhr,status,args,PF('buyDialog'));">
<p:confirm header="#{myBundle.ConfirmationHeader}" message="#{myBundle.ConfirmEditMessage}" icon="ui-icon-alert"/>
</p:commandButton>
<p:commandButton value="#{myBundle.Cancel}" oncomplete="PF('buyDialog').hide()" update="buyDisplay" process="#this" immediate="true" resetValues="true"/>
</h:panelGroup>
</h:form>
</p:dialog>
Where the save method is:
public void setBuyComment(long idPmMain, String commentText){
PmMain pmMain = pmMainFacadeEJB.find(idPmMain);
Comments comments = new Comments();
pmMain.setBuyComment(comments);
comments.setBuyComment(pmMain);
comments.setCommentText(commentText);
commentsFacadeEJB.edit(comments);
}
Everything works fine but I need to reload the page in order to visualize the comment id in PmMain (it gets inserted above where it says PmMain.setBuyComments(comments)). Any ideas?
EDIT
Adding information about setBuyComment:
For PmMain.setBuyComment I have:
public void setBuyComment(Comments buyComment) {
this.buyComment = buyComment;
}
And for comments.setBuyComment:
public void setBuyComment(PmMain pmMain){
pmMain.setBuyComment(this);
pmMainCollection24.add(pmMain);
}
EDIT 2
The backing Bean from PmMain looks like this:
#Entity
#Table(name = "pm_main")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "PmMain.findAll", query = "SELECT p FROM PmMain p")
, #NamedQuery(name = "PmMain.findByPropId", query = "SELECT p FROM PmMain p WHERE p.propId = :propId")
, #NamedQuery(name = "PmMain.findByPropName", query = "SELECT p FROM PmMain p WHERE p.propName = :propName")
, #NamedQuery(name = "PmMain.findByIdPmMain", query = "SELECT p FROM PmMain p WHERE p.idPmMain = :idPmMain")})
public class PmMain implements Serializable {
private static final long serialVersionUID = 1L;
#Size(max = 25)
#Column(name = "prop_id")
private String propId;
#Size(max = 125)
#Column(name = "prop_name")
private String propName;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_pm_main")
private Long idPmMain;
#JoinColumn(name = "buy_comment", referencedColumnName = "id_comments")
#ManyToOne
private Comments buyComment;
[... Getters and Setters ...]
And the Comments bean looks like:
#Entity
#Table(name = "comments")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Comments.findAll", query = "SELECT c FROM Comments c")
, #NamedQuery(name = "Comments.findByCommentText", query = "SELECT c FROM Comments c WHERE c.commentText = :commentText")
, #NamedQuery(name = "Comments.findByIdComments", query = "SELECT c FROM Comments c WHERE c.idComments = :idComments")})
public class Comments implements Serializable {
private static final long serialVersionUID = 1L;
#Size(max = 2147483647)
#Column(name = "comment_text")
private String commentText;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_comments")
private Long idComments;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "buyComment")
private List<PmMain> pmMainCollection24 = new ArrayList<>();
[... Getters and Setters ...]
public void setBuyComment(PmMain pmMain){
pmMain.setBuyComment(this);
pmMainCollection24.add(pmMain);
}

Related

One-to-many JPA EntityManager Primefaces

I have the following form inside a dialog:
<h:form id="CommentCreateForm">
<h:panelGroup id="display">
<p:outputPanel id="commentsPanel">
<p:row>
<p:column>
<p:inputTextarea id="commentText" value="#{commentsController.selected.commentText}" cols="100" rows="20" style="margin-bottom:10px"/>
</p:column>
</p:row>
</p:outputPanel>
<p:commandButton actionListener="#{commentsController.savePropReception}" value="#{myBundle.Save}" update="display,:PmMainListForm:datalist,:growl" oncomplete="handleSubmit(xhr,status,args,PF('CommentCreateDialog'));">
<p:confirm header="#{myBundle.ConfirmationHeader}" message="#{myBundle.ConfirmEditMessage}" icon="ui-icon-alert"/>
</p:commandButton>
</h:panelGroup>
</h:form>
With it's corresponding parent entity called Comments:
#Entity
#Table(name = "comments")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Comments.findAll", query = "SELECT c FROM Comments c")
, #NamedQuery(name = "Comments.findByCommentText", query = "SELECT c FROM Comments c WHERE c.commentText = :commentText")
, #NamedQuery(name = "Comments.findByIdComments", query = "SELECT c FROM Comments c WHERE c.idComments = :idComments")})
public class Comments implements Serializable {
private static final long serialVersionUID = 1L;
#Size(max = 2147483647)
#Column(name = "comment_text")
private String commentText;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_comments")
private Long idComments;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "propReceptionComment")
private List<PmMain> pmMainCollection5;
[... Getters and Setters ...]
public void setPropReception(PmMain pmMain){
pmMain.setPropReceptionComment(this);
pmMainCollection5.add(pmMain);
}
And it's child entity called PmMain:
#Entity
#Table(name = "pm_main")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "PmMain.findAll", query = "SELECT p FROM PmMain p")
, #NamedQuery(name = "PmMain.findByPropId", query = "SELECT p FROM PmMain p WHERE p.propId = :propId")
, #NamedQuery(name = "PmMain.findByPropName", query = "SELECT p FROM PmMain p WHERE p.propName = :propName")
, #NamedQuery(name = "PmMain.findByPropStatus", query = "SELECT p FROM PmMain p WHERE p.propStatus = :propStatus")
, #NamedQuery(name = "PmMain.findByIdPmMain", query = "SELECT p FROM PmMain p WHERE p.idPmMain = :idPmMain")})
public class PmMain implements Serializable {
private static final long serialVersionUID = 1L;
#Size(max = 25)
#Column(name = "prop_id")
private String propId;
#Size(max = 125)
#Column(name = "prop_name")
private String propName;
#Size(max = 25)
#Column(name = "prop_status")
private String propStatus;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_pm_main")
private Long idPmMain;
#JoinColumn(name = "prop_reception_comment", referencedColumnName = "id_comments")
#ManyToOne
private Comments propReceptionComment;
[... Getters and Setters ...]
And the CommentsController contains a method called savePropReception:
public void savePropReception(){
PmMain pmMain = new PmMain();
Comments comments = new Comments();
pmMain.setPropReceptionComment(comments);
comments.setPropReception(pmMain);
commentsFacadeEJB.edit(comments);
}
While commentsFacadeEJB contains:
public void edit(T entity) {
getEntityManager().merge(entity);
}
So, when a PmMain is already created, I can't get PmMain.propRecetionComment to update with the ID of a new 'Comments'. What am I missing?

Returning complex objects from Spring Data #Query

I'm writing a Questionnaire application (Java, Spring Boot, SQL) and I have a working query for returning the count of each answer in the database for specified questionnaire:
#Query(value = "SELECT new org.project.domain.AnswerCount(a.value, count(a)) FROM "
+ "Answer a WHERE a.questionnaire = :questionnaire GROUP BY a.value")
List<AnswerCount> findAnswerCountByQuestionnair(#Param("questionnaire") Questionnaire questionnaire);
Now what I would like to do is to group these AnswerCounts by what question they are answers to and store that in a list of QuestionResponseData objects. I could do it in Java code by some stream grouping methods, but I would prefer to do it directly in the query for speed.
Is that even possible, and what would be the best way to do that?
Here are the relevant parts of the models:
public class AnswerCount {
private String answer;
private long count;
}
.
public class QuestionResponseData {
private String question;
private String type;
private List<AnswerCount> answers;
}
.
/**
* A Answer.
*/
#Entity
#Table(name = "answer")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "answer")
public class Answer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#NotNull
#Column(name = "jhi_value", nullable = false)
private String value;
#ManyToOne
private Question question;
#ManyToOne
private Respondant respondant;
#ManyToOne
private Questionnaire questionnaire;
}
.
/**
* A Question.
*/
#Entity
#Table(name = "question")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "question")
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#NotNull
#Column(name = "text", nullable = false)
private String text;
#Enumerated(EnumType.STRING)
#Column(name = "jhi_type")
private QuestionType type;
#OneToMany(mappedBy = "question")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Answer> answers = new HashSet<>();
#ManyToMany(mappedBy = "questions")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Questionnaire> questionnaires = new HashSet<>();
}
I'm thinking something similar to this:
#Query(value = "SELECT new QuestionResponseData(q.text, q.type, answers) FROM "
+ "(SELECT new org.project.domain.AnswerCount(a.value, count(a)) as answerCount FROM "
+ "Answer a WHERE a.questionnaire = :questionnaire GROUP BY a.value") answers, "
+ "Question q WHERE answers.answerCount.question = q "
+ "GROUP BY answerCount.question")
but that obviously doesn't work...
Is it possible?

Criteria JPA - Specific attribute

I need to create a criteria query that represents the follow JPQL:
I tryed to specify the class RegraContrato but no success.
SELECT G FROM Grupo G JOIN G.regras R WHERE TYPE(R) = RegraContrato AND R.numeroContrato in(123)
#Entity
#Table(name = "GRUPO_ACESSO")
public class Grupo {
#OneToMany(mappedBy = "grupo",cascade = CascadeType.ALL,fetch = FetchType.EAGER,orphanRemoval = true)
private Set<Regra> regras = Sets.newHashSet();
}
#Entity
#Table(name = "REGRA_ACESSO")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Regra {
private static final long serialVersionUID = 5994730323053219858L;
#Id
#SequenceGenerator(name = "REGRA_ID_GENERATOR",sequenceName = "REGRA_SEQUENCE",allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "REGRA_ID_GENERATOR")
#Column(name = "ID")
private Long id;
}
#Entity
#PrimaryKeyJoinColumn(name = "ID")
#Table(name = "REGRA_CNPJ")
public class RegraCNPJ extends Regra {
#Column(name = "CNPJ")
private String cnpj;
}
#Entity
#PrimaryKeyJoinColumn(name = "ID")
#Table(name = "REGRA_CONTRATO")
public class RegraContrato extends Regra {
private static final long serialVersionUID = -2840125767126128182L;
#Column(name = "NUMERO_CONTRATO")
private Long numeroContrato;
}

Netbeans wizard Entity Classes from Database, not all tables mapped

I used this wizard to create entity classes from my database. Some tables have not been transformed into classes, but there are attributes that identify the relationships.
this is my db ERD (mysql)
and this is the user entity class (attributes)
#Entity
#Table(name = "user")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findByOid", query = "SELECT u FROM User u WHERE u.oid = :oid"),
#NamedQuery(name = "User.findByUsername", query = "SELECT u FROM User u WHERE u.username = :username"),
#NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password"),
#NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email"),
#NamedQuery(name = "User.findByAddress", query = "SELECT u FROM User u WHERE u.address = :address"),
#NamedQuery(name = "User.findBySince", query = "SELECT u FROM User u WHERE u.since = :since")})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "oid")
private Integer oid;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 15)
#Column(name = "username")
private String username;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 15)
#Column(name = "password")
private String password;
// #Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 30)
#Column(name = "email")
private String email;
#Size(max = 50)
#Column(name = "address")
private String address;
#Basic(optional = false)
#NotNull
#Column(name = "since")
#Temporal(TemporalType.DATE)
private Date since;
#JoinTable(name = "favorite", joinColumns = {
#JoinColumn(name = "user_oid", referencedColumnName = "oid")}, inverseJoinColumns = {
#JoinColumn(name = "wheelchair_oid", referencedColumnName = "oid")})
#ManyToMany
private List<Wheelchair> wheelchairList;
#ManyToMany(mappedBy = "userList1")
private List<Wheelchair> wheelchairList1;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "senderOid")
private List<Comment> commentList;
#JoinColumn(name = "role_oid", referencedColumnName = "oid")
#ManyToOne(optional = false)
private Role roleOid;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userOid")
private List<Orthopedy> orthopedyList;
public User() {
}
...
i can't understand something:
where is the OWN join table?
why i have userList1 and wheelchairList1? should it identifies OWN table? in this case i can rename it here or i have to rename it in some xml file?
why of
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userOid")
private List<Orthopedy> orthopedyList;
?
it should be OneToOne...
moreover the "JSF from entities class" wizard creates CRUD operation to manage Users, how can i manage join tables? I need to write something in the controller like what?
can you please link me some resource where i can learn this?
thank you so much
While Creating Entities It Creates Classes For All Tables With Primary Key
But not for tables that have many to many relations . its managed by their parent classes it is maintained as a list.
This is my code for managing my many to many table of SubjectFaculty which has details of Faculty and Subjects
Assigning A Subject To Faculty
public void assignFacultyToSubject(String facultyUname, Integer subjectId) {
try {
Subject oSubject = em.find(Subject.class, subjectId);
Faculty oFaculty = em.find(Faculty.class, facultyUname);
College oCollege = em.find(College.class, oFaculty.getCollegeUname().getCollegeUname());
List<Faculty> lstFaculty = oSubject.getFacultyList();
List<Subject> lstSubject = oFaculty.getSubjectList();
if (!lstSubject.contains(oSubject)) {
lstFaculty.add(oFaculty);
lstSubject.add(oSubject);
oSubject.setFacultyList(lstFaculty);
oFaculty.setSubjectList(lstSubject);
em.merge(oSubject);
em.getEntityManagerFactory().getCache().evictAll();
} else {
System.out.println("Entry Already Found");
}
} catch (Exception e) {
System.out.println("Error :- " + e.getMessage());
}
}
Removing Subject And Faculty Details Form Many to Many Table
#Override
public void removeFacultySubject(String facultyUname, Integer subjectId) {
try {
Subject oSubject = em.find(Subject.class, subjectId);
Faculty oFaculty = em.find(Faculty.class, facultyUname);
List<Subject> lstSubject = oFaculty.getSubjectList();
List<Faculty> lsFaculty = oSubject.getFacultyList();
lstSubject.remove(oSubject);
lsFaculty.remove(oFaculty);
em.merge(oSubject);
} catch (Exception e) {
System.out.println("Error :- " + e.getMessage());
}
}

How to get the Max of Total in JPA?

Hi I have to write JPQL command that does something specific the question is exactly:
"Find those students that has the greatest total of studypoint scores?"
There are just two Entity classes that looks like :
#Entity
#Table(name = "student")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Student.findAll", query = "SELECT s FROM Student s"),
#NamedQuery(name = "Student.findById", query = "SELECT s FROM Student s WHERE s.id = :id"),
#NamedQuery(name = "Student.findByFirstname", query = "SELECT s FROM Student s WHERE s.firstname = :firstname"),
#NamedQuery(name = "Student.findByLastname", query = "SELECT s FROM Student s WHERE s.lastname = :lastname")})
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "LASTNAME")
private String lastname;
#OneToMany(mappedBy = "studentId", cascade = CascadeType.PERSIST)
private List<Studypoint> studypointCollection;
public void addStudyPoint(Studypoint cc) {
if (studypointCollection == null) {
studypointCollection = new ArrayList<>();
}
studypointCollection.add(cc);
cc.setStudentId(this);
}
and the other class
#Entity
#Table(name = "studypoint")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Studypoint.findAll", query = "SELECT s FROM Studypoint s"),
#NamedQuery(name = "Studypoint.findById", query = "SELECT s FROM Studypoint s WHERE s.id = :id"),
#NamedQuery(name = "Studypoint.findByDescription", query = "SELECT s FROM Studypoint s WHERE s.description = :description"),
#NamedQuery(name = "Studypoint.findByMaxval", query = "SELECT s FROM Studypoint s WHERE s.maxval = :maxval"),
#NamedQuery(name = "Studypoint.findByScore", query = "SELECT s FROM Studypoint s WHERE s.score = :score")})
public class Studypoint implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
#Column(name = "DESCRIPTION")
private String description;
#Column(name = "MAXVAL")
private Integer maxval;
#Column(name = "SCORE")
private Integer score;
#JoinColumn(name = "STUDENT_ID", referencedColumnName = "ID")
#ManyToOne
private Student studentId;
As you can see Student can have many Studypoints. Which I really struggle is this JPQl: Please help.
I tried for sometime to get this working with JQL and I can't see how you wrap the max in the sum, so I switched to SQL.
It's not ideal, but here is my repository:
package net.isban.fmis.repository;
import net.isban.fmis.entity.Studypoint;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface StudyPointRepository extends CrudRepository<Studypoint, Integer> {
#Query(value="select top 1 id from (select sum(score) scoresum, student.id from studypoint join student on student.id=studypoint.student_id group by student.id) order by scoresum desc", nativeQuery=true)
Integer findStudentIdWithMaxScore();
}