Compare enum with list Thymeleaf - java

I have an enum inserted in an entity, with some default values. I want to compare this with the enums assigned to the entity.
I tried looking for the enum string in the list, but I don't get a result
public class Role{
#NotEmpty
#Enumerated(value = EnumType.STRING)
private Authority authority;
public static enum Authority {
ROLE_ADMIN,
ROLE_USER
}
}
public class UserCheck implements UserDetails {
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_id")
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
}
the enum is traversed and compared to the list
<div class="form-group">
<label for="exampleSelectStore">Roles</label> <select class="form-control" id="exampleSelectStore" multiple="multiple">
<option th:each="authority : ${T(cl.tricotcorp.app.checklist.models.entity.Role.Authority).values()}" th:text="${authority}" th:value="${authority}" th:selected="${#lists.contains(userCheck.getRoles(), authority)}"> </select>
</div>
the expected result is to mark the matches as "checked"

getRoles() returns a List<Role>, and authority is an Authority, so you're basically asking if any Role.equals(Authority), which by definition is always false.
One way to fix it, so its easy to use, is to add a helper method to UserCheck:
public boolean hasAuthority(Authority authority) {
return this.roles.stream().anyMatch(r -> r.getAuthority() == authority);
}
Then your Thymeleaf code would be:
<option ... th:selected="${userCheck.hasAuthority(authority)}">

Related

Get Userlist with rolename in spring boot

In My spring boot Application, I want to see total userlist like below:
username
role
admin
ADMIN
But i got like:
username
role
admin
[com.test.springCRUD.model.Role#3e39aaf6]
My User model:
#Entity
#Table(name = "users")
public class User {
#Id
#Column(name="user_id")
#GeneratedValue(strategy =GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private boolean enabled;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name ="users_roles", joinColumns = #JoinColumn (name="user_id"), inverseJoinColumns = #JoinColumn (name="role_id"))
private Set<Role> roles=new HashSet<>();
Role model:
#Entity
#Table(name = "roles")
public class Role {
#Id
#Column(name="role_id")
#GeneratedValue(strategy =GenerationType.IDENTITY)
private Integer id;
private String name;
UserService Class:
#Service
public class UserServices {
#Autowired
private UserRepository userRepository;
public List<User> listAll(){
return (List<User>) userRepository.findAll();
}
Controller:
#RequestMapping("/userlist")
public String viewUserList(Model model) {
List<User> listUsers = userServices.listAll();
model.addAttribute("listUsers", listUsers);
return "userList";
}
thymleaf page:
<tbody>
<tr th:each="user : ${listUsers}">
<td th:text="${user.id}">User ID</td>
<td th:text="${user.username}">User Name</td>
<td th:text="${user.roles}">User Role</td>
<td>
</td>
</tr>
</tbody>
How to get userlist with rolename.
I am on a similar project.
'roles' is defined as a Set of Roles, so you are seeing the identifiers of that object, rather than the values.
You will need to iterate through the roles themselves if the intent is to display the list of names of roles.
Also remember, the role has a name and Id since it in itself is an entity/model, so you will want to iterate the roles and show role name, something like:
- <el th:each="role : ${user.getRoles()}"/>
- <el th:text="${role.getName()}"/>
If you are liking the Table, I would recommend a span for each role name.
There are alternatives depending on how you want it shown. You may also do this in your controller or UserDetails class depending on what the desired functionality/application or display is beyond verifying it within a thymeleaf page for users or Admins.

Form that when updating current client, removes child table information connected to parent table

In my Spring-boot, Java, and Thymeleaf application, I have a form that is filled out once with new client information and is saved to SQL database table. When you want to edit this client's information, and click save, it ends up saving/updating the info but also removing information in a SQL child table, called ResourceWebsiteAccess. I can't tell if it is updating the info and there's a problem with the child table, or if it is just replacing all the clients information and therefore deleting the child table information. Any ideas what is going wrong and how to go about fixing it?
Here is some of the html form:
<form enctype="multipart/form-data" th:action="${clientEndpoint}" method="post" th:object="${client}" class="tab-content">
<div class="tab-pane" id="prospect-profile">
<div th:replace="prospectProfile :: prospect-profile"></div>
</div>
<div class="tab-pane" id="affiliates">
<div class="row">
<h4>Affiliate Competency</h4>
<br/>
<div th:replace="affiliates/personalLines :: personal-lines"></div>
</div>
<hr/>
<div class="row">
<div th:replace="affiliates/commercialLines :: commercial-lines"></div>
</div>
<hr/>
</div>
<input id="submitButton" type="submit" value="Save" name="save" class="btn btn-success finish" data-loading-text="Saved!" disabled="true"/><br/>
</form>
This is the controller action that occurs when you hit the save "button".
#RequestMapping(value="/saveClient")
#ResponseBody
public JSONObject saveClient(Model model, #ModelAttribute(value="client") Client client)
{
Boolean saved=false;
JSONObject response=new JSONObject();
Client clientBeforeUpdate=clientRepository.findById(client.getId());
if (clientBeforeUpdate!=null && !clientBeforeUpdate.getStatus().equals("active") && client.getStatus().equals("active"))
client.setOnboardedDate(LocalDate.now());
else if (!client.getStatus().equals("active"))
client.setOnboardedDate(null);
try{
client=clientRepository.save(client);
saved=true;
response.put("clientId",client.getId());
}catch (DataAccessException e) {
e.printStackTrace();
response.put("error",e.getLocalizedMessage());
response.put("cause",e.getLocalizedMessage());
}
response.put("success",saved);
return response;
}
Client Repository:
#Transactional
public interface ClientRepository extends CrudRepository<Client,Long>, JpaSpecificationExecutor {
Client save(Client entity);
List<Client> findByPrincipleNameContaining(String principleName);
List<Client> findByNdaSent(Boolean ndaSent);
List<Client> findByLegalNameContaining(String legalName);
List<Client> findByYearsExperienceContaining(String yearsExperience);
List<Client> findByLicenses(String licenses);
Client findById(Long id);
void delete(Client entity);
List<Client> findAll();
#Query("SELECT c FROM Client c Where c.status = 'active' AND ((c.contractExecuted=false OR c.agencyLicenseReceived=false OR c.eoReceived=false OR c.w9 =false OR c.directDepositCommissionAgreement=false) OR c.licenses!='Accident & Health' AND (c.producerAppointmentForm=false OR c.prepaymentAuthorizationAms360=false))")
List<Client> findClientsMissingDocs();
List<Client> findByNdaSentAndNdaSentDateBetween(Boolean ndaSent,LocalDate start,LocalDate end);
List<Client> findByContractSubmittedAndContractSubmittedDateBetween(boolean b, LocalDate startOfMonth, LocalDate now);
List<Client> findByStatus(String prospect);
}
Here is some of client.java, the model for the form.
#Entity
#Table(name="Client")
#EntityListeners(AuditingEntityListener.class)
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ClientId")
private Long id;
...
#OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
#JoinColumn(name = "client")
private List<Employee> employees= new ArrayList<>();
#OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
#JoinColumn(name = "client")
private List<VendorService> vendorServices=new ArrayList<>();
#OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
#JoinColumn(name="client")
private List<ResourceWebsiteAccess> resourceWebsiteAccess=new ArrayList<>();
public List<ResourceWebsiteAccess> getResourceWebsiteAccess() {
return resourceWebsiteAccess;
}
public void setResourceWebsiteAccess(List<ResourceWebsiteAccess> resourceWebsiteAccess) {
this.resourceWebsiteAccess = resourceWebsiteAccess;
}
}
Here is the model for the ResourceWebsiteAccess, this doesnt have an individual controller, but it does have its on Repository
#Entity
#Table(name = "ResourceWebsiteAccess")
public class ResourceWebsiteAccess {
#Override
public String toString() {
return micrositeLink;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ResourceWebsiteAccessId")
private Long id;
private String micrositeLink;
private String partnerPortalLink;
#OneToOne
#JoinColumn(name = "client")
private Client client;
...
}
How I am adding the information to the child table, via a form, that uses this controller:
#RequestMapping(value="/settings/client/{id}")
public String links(#PathVariable("id")Client client, Model model){
ResourceWebsiteAccess access= accessRepository.findByClient(client);
if (access==null)
access= new ResourceWebsiteAccess();
model.addAttribute("client",client);
model.addAttribute("newUser",new ResourceWebsiteUser());
model.addAttribute("users",repository.findByClient(client));
model.addAttribute("access",access);
return "settings";
}
ResourceWebsiteAccess Repository:
#Transactional
public interface ResourceWebsiteAccessRepository extends CrudRepository<ResourceWebsiteAccess,Long>,JpaSpecificationExecutor {
ResourceWebsiteAccess findByClient(Client client);
}
The problem you are having, is that you are updating all fields, including those that are coming as null from your form. What you really want to do, is update only those values that were modified. To do this, you can use Hibernate's #DynamicUpdate annotation on your entity.
#Entity
#DynamicUpdate
#Table(name="Client")
#EntityListeners(AuditingEntityListener.class)
public class Client { ... }
You can read more about this in the following blog.
Another way to achieve what you are trying to do, is fetching the client by it's id and then set the new values with the ones you just received from your form.
#RequestMapping(value="/saveClient")
#ResponseBody
public JSONObject saveClient(Model model,
#ModelAttribute(value="client") Client client) {
Boolean saved=false;
JSONObject response=new JSONObject();
Client clientBeforeUpdate=clientRepository.findById(client.getId());
if (clientBeforeUpdate!=null && !clientBeforeUpdate.getStatus().equals("active") && client.getStatus().equals("active"))
clientBeforeUpdate.setOnboardedDate(LocalDate.now());
else if (!client.getStatus().equals("active"))
clientBeforeUpdate.setOnboardedDate(null);
try{
// Set the rest of the needed changes from your new client.
clientBeforeUpdate=clientRepository.save(clientBeforeUpdate);
saved=true;
response.put("clientId",client.getId());
}catch (DataAccessException e) {
e.printStackTrace();
response.put("error",e.getLocalizedMessage());
response.put("cause",e.getLocalizedMessage());
}
response.put("success",saved);
return response;
}
Since you were saving ResourceWebsiteAccess separately add insertable and updatable false in #JoinColumn
#OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
#JoinColumn(name="client",insertable=false,updatable=false)
private List<ResourceWebsiteAccess> resourceWebsiteAccess=new ArrayList<>();
I ended up adding #DynamicUpdate to the model, removing OrphanRemoval= true; in the model, and adding client.setResourceWebsiteAccess(clientBeforeUpdate.getResourceWebsiteAccess());to the controller.
These three steps fixed my issue and now everything is displaying.
Thanks to #AlianCruz

Why this Thymeleaf form binding with selection field does not work?

I have two models, Patient and Study. In the Study model, I want to use Patient's Id as a foreign key. My Study Model (without getter/setter) is as below
#Entity
#Table(name = "Study")
public class Study {
#Id
#Column(name = "study_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#ManyToOne
#JoinColumn(name = "patient_id")
private Patient patient;
#NotNull
#Column(name = "description")
private String description;
#NotNull
#Column(name = "status")
private String status;
}
EDIT : Adding Patient class (without getter/setter) as well
#Entity
#Table(name="Patient")
public class Patient {
#Id
#Column(name="patient_id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#NotNull
#Column(name="name")
private String name;
#Column(name="sex")
private String sex;
#Column(name="date_of_birth")
private Date dateOfBirth;
}
I am using Thymeleaf and selection of patient in my scheduleStudy.html is shown below
<form method="POST" th:action="#{/scheduleStudy}" th:object="${study}">
<p>
Select Patient<select th:field="*{patient}"
required="required" class="form-control">
<option th:each="patient: ${patientList}" th:value="${patient.id}"
th:text="${patient.name}"></option>
</select>
</p>
The form is loading successfully with list of Patients in dropdown. However, when I am submitting the form after filling out all the fields, I am receiving:
Validation failed for object='study'. Error count: 1 error on browser.
Also the controller entries for Study form
#GetMapping("/scheduleStudy")
public String addSchedule(Model model) {
List<Patient> patientList = patientService.getPatients();
model.addAttribute("patientList", patientList);
model.addAttribute("study", new Study());
return "scheduleStudy";
}
#PostMapping("/scheduleStudy")
public void processAddSchedule(#ModelAttribute Study study) {
studyService.addStudy(study);
}
I have just started using Thymeleaf and I think I have dome some mistake in the patient field. Could anyone please help?
EDIT 2: I have updated the method for POST request, but patient is still null in controller. The previous browser error is gone of course.
#RequestMapping(value = "/scheduleStudy", method = RequestMethod.POST)
public String processAddSchedule(Model model, #Valid #ModelAttribute("study") Study study,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
} else {
studyService.addStudy(study);
}
}
I was working on a similar task. As far as I learned when you post the study form Thymeleaf sends all fields as parameters to a POST request. It converts the Patient object to a String with toString(). Then when assembling the Study object it must convert the Patient back to the Object form. I solved this by registering 2 converters (toString and fromString) with the standard conversionService for Patient.

Get child count using hibernate in springmvc

If we are creating a backend for website. We will obviously create categories and posts/products. To add/edit/delete categories we will obviously create a table like structure. for example:This is category listing as table
Category would have a child category in a same table, number of child category could be 1 - many. I would like to show the number of child category as i have mentioned in above image.
As a CI developer i use to do that by using Query in the view,
Here is the example
<?php
if(sizeof($results)>0)
{
$i=1;
foreach($results as $key => $list)
{
if($i%2==0)$cls="row1"; else $cls="row2";
?>
<tr id="<?php echo $list->id;?>" class="<?php echo $cls; ?>">
<td> <?php echo $list->title, anchor("admin/categories/update/".$list->id."/", '<i class="fa fa-pencil rtrt"></i>' ); ?></td>
<td>
<?php
// it will return number of childs
echo anchor ('admin/categories/category/'.$list->id, $this->Common->select_child ('tbl_category', $list->id) );
?>
</td>
Right now i am using Spring-mvc, hibernate, Jpa, and Mysql DB. I am known that doing sql query from a jsp would be a bad practice.
Here is my Jsp Code for table like structure,
<table class="table table-striped">
<thead>
<tr>
<th><i class="fa fa-pencil"></i></th>
<th>Category Name</th>
<th>Child</th>
<th>Created</th>
<th>Updated</th>
<th><input type="checkbox" /></th>
</tr>
</thead>
<tbody>
<c:if test="${not empty category}">
<c:forEach var="cat" items="${category}">
<tr>
<td><i class="fa fa-pencil"></i></td>
<td>${cat.title}</td>
<td><i class="fa fa-folder-open"></i></td>
<td>${cat.created}</td>
<td>${cat.updated}</td>
<td><input type="checkbox" /></td>
</tr>
</c:forEach>
</c:if>
Here is the category POjo class
#Entity
#Table(name = "categories")
public class Categories {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private Long parent_id;
private String title;
private String url_title;
private String description;
private String created;
private String updated;
/*
* # At the time of Creating new user
* Auto persist created date
* Auto persist updated for first time
*/
#PrePersist
protected void onCreate (){
// Date conversion to string
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd h:mm:s");
sdf.setLenient(false);
String now = sdf.format(date);
created = now;
updated = now;
}
/*
* Respective Getter and Setter Methods
*
*/
public Long getId() {
return id;
}public void setId(Long id) {
this.id = id;
}
public Long getParent_id() {
return parent_id;
}public void setParent_id(Long parent_id) {
this.parent_id = parent_id;
}
public String getTitle() {
return title;
}public void setTitle(String title) {
this.title = title;
}
public String getUrl_title() {
return url_title;
}public void setUrl_title(String url_title) {
this.url_title = url_title;
}
public String getCreated() {
return created;
}public void setCreated(String created) {
this.created = created;
}
public String getUpdated() {
return updated;
}public void setUpdated(String updated) {
this.updated = updated;
}
public String getDescription() {
return description;
}public void setDescription(String description) {
this.description = description;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Categories other = (Categories) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
The Question is
how can i get children count without doing sql query from Jsp ?
Please Help me i need a suggestion.
to get a List count on jsp side use jstl functions like below :
declare the taglibe of jstl.functions
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
then you can try this
<c:set var="count" value="${fn:length(you_array)}" />
this will create a variable "count" taking as value : you_array.size()
Hope it will help someone like me,
Modified entity class
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private Long parent_id;
private String title;
private String url_title;
private String description;
private Long status;
private String created;
private String updated;
#ManyToOne
#JoinColumn(
name="parent_id",
insertable=false,
updatable=false)
#NotFound(action = NotFoundAction.IGNORE)
private Categories parentCategory;
#OneToMany(
fetch = FetchType.EAGER,
mappedBy="parentCategory",
cascade=CascadeType.REMOVE,
orphanRemoval=true )
private Set<Categories> child = new HashSet<Categories>();
Since i am new to Jpa/orm/hibernate/spring when i posted this question i did not knew about entity relationship which we can manage in hibernate. I did some research and found out about hibernate 'Uni/Bi directional' association using annotation like (one to many, many to one, many to many). I suggest if you are new to JPA and hibernate then please visit This link before wasting your time.
What I have done
Bidirectional associations with join : using #ManyToOne #Onetomany #joinColumn
Solve Notfound exception using #NotFound(NotFoundAction.IGNORE)
I have a categories (eg. Base category) which wont have any parent category so its 'parent_id' will be 0 in database but Hibernate will throw exception while querying records from database with id 0, after a successfull association.
Used insertable/updatable = false : set this properties to false if you are inserting and updating only one category at a time.
Used "cascade=cascadetype.remove" "orphanremoval=true" : set this properties, if you want to delete child categories when you delete parent category. When you invoke your serviceImplementation.delete(category cat) method, if "cat:object" is parent for other categories hibernate will automatically delete it's children categories before deleting cat:object itself.
At last the Answer for my question
After the successful association with annotation, when you will query category rows from database. If it's a parent category for other categories hibernate will add "child Collection" in your object like this.
03:20:16.490 [http-bio-8080-exec-5] DEBUG
o.h.internal.util.EntityPrinter -
com.pack.librarymanagementsystem.model.Categories
{created=2016-06-10 7:45:32, parent_id=38, url_title=Bhm 5th sem,
description=<p>asd</p>,
parentCategory=com.pack.librarymanagementsystem.model.Categories#38,
id=43, title=Bhm 5th sem, updated=2016-06-10 7:45:32, child=[], status=1}
Check It in your console log if you are using eclipse. The child collection hibernate just added wont have any data. Hibernate will store only proxys.
The solution is to get the size of a child collection.
If you will do isEmpty() check on that child collection the result will be true. Thats where the "fetch = FetchType.EAGER" Kicks in. By default fetchtype is set to lazy. After changing fetchtype to eager hibernate will add objects as a child instead of adding proxy.
If you will do isEmpty check on that child collection now, the result will be false. Which means we can get the size of a collection.
This is the jsp
<c:if test="${not empty category}">
<c:forEach var="cat" items="${category}">
<tr>
<td><i class="fa fa-pencil"></i></td>
<td>${cat.title}</td>
<td>
// Child count
<c:if test="${not empty cat.child}" >
<a href="${pageContext.request.contextPath}/category/show/${cat.id}">
<i class="fa fa-folder-open"></i> ${ fn:length(cat.child)}
</a>
</c:if>
<c:if test="${empty cat.child}" >
<i class="fa fa-folder"></i> 0
</c:if>
</td>
<td>${cat.created}</td>
<td>${cat.updated}</td>
<td>
<c:choose>
<c:when test="${cat.status == 1}">Published</c:when>
<c:otherwise>Unpublished</c:otherwise>
</c:choose>
</td>
<td><input type="checkbox" name="ids[]" id="ids[]" value="${cat.id}" /></td>
</tr>
</c:forEach>
And this is the controller
#RequestMapping(value = "/show/", method = RequestMethod.GET)
public String viewCategory( Map<String, Object> model) {
List<Categories> category = categoryService.getAllCategoriesByParent(Id);
model.put("category",category);
return "category/view";
}
I hope this would help someone on saving his/her time.
Thank you

How to access attribute of attribute of object in thymeleaf?

Say I want to access an object that is called post. Post has a instance variable called Category of type Category.
In the Java controller class
model.addAttribute("posts", postRepository.findPostsByUser(user));
In the thymeleaf html file I have
<tr data-th-each="post : ${posts}">
I am wondering if it is it possible to access the below?
{post.category.name}
For clarification I have included the java classes below. Each instance has associated setters and getters.
#Entity
public class Post {
#ManyToOne
#JoinColumn(name = "category_id")
private Category category;
#Entity
public class Category {
private String name;
you have to make a condition:
<tr th:each="post:${posts}">
<td th:text="${post.category}!=null? ${post.category.name}:''"></td>
</tr>
:)
I think you need to change your entity code
#Entity
public class Post {
private Category category;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "category_id", nullable = false)
public Category getCategory () {
return this.category;
}
public void setCategory (Category category ) {
this.category = category ;
}
}
you need implement thymeleaf html page as per following
<tr th:each="post : ${posts}">
<td> <span th:utext="{post.category.name}" /></td>
</tr>
Hope its help to you!

Categories