Object null in View layer - spring

i have this problem:
O pedido:
#Entity
#Table(name="wp_posts")
public class Pedido implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Column(name="post_status")
private String status;
#Column(name="post_type")
private String tipo;
#OneToMany(mappedBy = "pedido", cascade=CascadeType.ALL, orphanRemoval = true)
private List<PedidoMeta> pedidoMeta;
#OneToMany(mappedBy = "pedido", cascade=CascadeType.ALL, orphanRemoval = true)
private List<PedidoItem> itens;
#Column(name="post_date")
private Date data;
#Transient
private Usuario cliente;
O Controller:
#GetMapping(value = "/detalhePedido/{id}")
public ModelAndView detalhePedido( #PathVariable(value = "id", required = false) String pedidoid) {
pedido = pedidoRepository.findOne(new Long(pedidoid));
pedido = pedidoService.findCliente(pedido);
ModelAndView modelAndView = new ModelAndView("DetalhePedido");
modelAndView.addObject("pedido",pedido);
return modelAndView;
}
a View:
<tbody>
<tr th:object="${pedido}">
<td th:text="*{pedido.id}"></td>
<td th:text="*{pedido.cliente.nome}"></td>
<td th:text="*{#dates.format(pedido.data, 'dd-MM-yyyy')}"></td>
</tr>
</tbody>
O erro:
org.springframework.expression.spel.SpelEvaluationException: EL1008E:
Property or field 'pedido' cannot be found on object of type 'com.ledolate.sys.model.Pedido' - maybe not public?
When debugging, the request is correct, with all the information, but when receiving in the visual layer it presents this error.

Welcome to SO.
The issue is in your HTML. You may want simply:
<tbody>
<tr>
<td th:text="${pedido.id}"></td>
<td th:text="${pedido.cliente.nome}"></td>
<td th:text="${#dates.format(pedido.data, 'dd-MM-yyyy')}"></td>
</tr>
</tbody>
Or, if you are using th:object, then you're telling Thymeleaf that you are selecting the pedido variable and therefore shouldn't specify it again (unless pedido has a property also called pedido):
<tbody th:object="${pedido}">
<tr>
<td th:text="*{id}"></td>
<td th:text="*{cliente.nome}"></td>
<td th:text="*{#dates.format(data, 'dd-MM-yyyy')}"></td>
</tr>
</tbody>
The error message states exactly this.
See the docs for examples.

Related

spring boot and thymeleaf

I need help with spring enter image description hereboot and thymeleaf because it doesn't show me the user roles
because it shows me this information and not the roles
this is my database
enter image description here
my controller
#GetMapping("/listar")
public String listar(Model model) {
List<User> listUsers= userService.findAll();
if(listUsers !=null) {
model.addAttribute("titulo", "Lista de usuarios y roles");
model.addAttribute("listUsers", listUsers);
return "user/listar";
}
return "redirect:/escuela/";
}
My HTML
<tr th:each="user: ${listUsers}">
<td th:text="${user.nombre}"></td>
<td th:text="${user.aPaterno}"></td>
<td th:text="${user.aMaterno}"></td>
<td th:text="${user.curp}">]</td>
<td th:text="${user.puesto}"></td>
<td th:text="${user.email}"></td>
<td th:text="${user.roles}"></td>
</tr>
my entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Size(min = 2, max = 20)
#NotBlank
private String nombre;
#Size(min = 2, max = 20)
#NotBlank
private String aPaterno;
#Size(min = 2, max = 20)
#NotBlank
private String aMaterno;
#Size(min = 18, max = 18)
#Column(length = 18, nullable = false, unique = true)
private String curp;
#Size(min = 2, max = 20)
#NotBlank
private String puesto;
#Email
#Column(length = 45, nullable = false, unique = true)
private String email;
#Size(min = 2, max = 20)
#Column(length = 20, nullable = false)
#NotBlank
private String password;
#Valid
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<Role>();
gettters and setters.....
I don't have much spring boot experience, can someone help me
You are getting this because the ${user.roles} is a list, so what's displayed is this list's (and consequently the Role's) default toString() method,
You need to loop in your user.roles and print, for example, the role's name like below:
<tr th:each="user: ${listUsers}">
<td th:text="${user.nombre}"></td>
<td th:text="${user.aPaterno}"></td>
<td th:text="${user.aMaterno}"></td>
<td th:text="${user.curp}">]</td>
<td th:text="${user.puesto}"></td>
<td th:text="${user.email}"></td>
<td>
<table>
<tr th:each="role: ${user.roles}">
<td th:text="${role.name}"></td>
</tr>
</table>
</td>
</tr>
For the sake of complicity you could also override the toString() method in your Role class and let your HTML as is, i.e.
<td th:text="${user.roles}"></td>
Since you haven't posted Role class below is a "guess" of what it might be and the toString() method is overridden to display the name field.
Role class
#Entity
public class Role {
private String name;
// rest of properties
// getters and setters
#Override
public String toString() {
return this.name;
}
}

Cannot show mysql data using jpa and thymeleaf

I'm very new to Spring. I'm trying to build an user management web app.
Here is the controller
#Controller
#RequestMapping("/index")
public class UserManagementController {
#Autowired
private UserManagementRepository userManagementRepository;
#RequestMapping(method= RequestMethod.GET)
public ModelAndView index(Model model){
ArrayList<Staff> staffList = (ArrayList<Staff>) userManagementRepository.findAll();
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("staffList", staffList);
return modelAndView;
}
}
The model
#Entity
#Table(name="staff")
#Data
public class Staff {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
private int age;
private String department;
private String sex;
private String status;
}
html file
<tbody>
<tr th:each="staff, state : ${staffList}">
<td th.text="${staff.id}"></td>
<td th.text="${staff.name}"></td>
<td th.text="${staff.age}"></td>
<td th.text="${staff.department}"></td>
<td th.text="${staff.department}"></td>
<td th.text="${staff.status}"></td>
</tr>
and finally the application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/user_management
spring.datasource.username=root
spring.datasource.password=
When i run the project, the table only shows the header and the body is totally blank.
I am not 100% sure but can you try to make all attributes in model public or generate getters and then change your code like:
<td th.text="${staff.getId()}"></td>
Do this:
<tr th:each="staff : ${staffList}">
That will solve your problem If not then comment below and tell whats the problem.
This should work :
<tr th:each="staff : ${staffList}">
<td th:text="${staff.id}"></td>
...
</tr>
If it doesn't, look with a debugger if the value staffList in your controller is not empty or null. If it is, then you have an issue with your database connection or request.

Haw can i show the details of each with using many to many relationship using spring and thymeleaf

I want to display the details of each user here is my class entity
#Entity
#Table(name="user")
public class User implements Serializable{
#Id #GeneratedValue
private Long id;
private String nom ;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="user_user_detail",joinColumns={
#JoinColumn(name="id")},
inverseJoinColumns={#JoinColumn(name="UserId")})
private Collection<UserDetail>userDetail ;
classe user detail
#Entity
#Table(name="userDetail")
public class UserDetail implements Serializable{
#Id #GeneratedValue
private Long UserId;
private String adresse ;
My controller
#RequestMapping(name="/vue", method = RequestMethod.GET)
public String vue(Model model){
User u=new User();
List<User>p=new ArrayList<User>();
p.add(u);
p=ur.findAll();
model.addAttribute("us",p);
return "user" ;
}
My view thymeleaf
<table border="1">
<tr>
<td>Nom</td>
<td>adresse</td>
</tr>
<tr th:each="t:${us}">
<td th:text="${t.Id}"></td>
<td th:text="${t.nom}"></td>
<td th:text="${t.getUserDetail()}"></td>
</tr>
</table>
i would to show the userdetail with
${t.getUserDetail()}">
but the result of details like this [org.sid.entity.UserDetail#1469f77e, org.sid.entity.UserDetail#78a81727]
please answer me quickly
thank's in advance

How to display an object that contains another object in thymeleaf

Hi I struggling to build a proper view in case, when I want to display the product entity, which is in a many-to-many relation with the category. The problem starts with the nested category. I have an error: Exception evaluating SpringEL expression: "category.name" (productList: 31) I will be very grateful for your help in solving this problem
View:
<tbody>
<tr data-th-each="product : ${products}">
<!--<td><input hidden="hidden" name="id" th:value="${product.id}" /></td>-->
<td th:text="${product.name}"></td>
<td th:text="${product.price}"></td>
<td th:each="category : ${product.categories}"></td>
<td th:text="${category.name}"></td>
<td th:text="${product.description}"></td>
<td th:text="${product.shippingWeight}"></td>
<td th:text="${product.quantity}"></td>
<td>delete</td>
</tr>
</tbody>
Entities:
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#Entity
#Table(name = "products")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "product_id")
private Long id;
private String name;
private BigDecimal price;
#ManyToMany(cascade = CascadeType.ALL,mappedBy = "products")
private List<Category> categories=new ArrayList<>();
private double shippingWeight;
private boolean isAvailable;
private String description;
private int quantity;
#Transient
private MultipartFile image;
Category:
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Entity
#Table(name = "categories")
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "category_id")
private Long id;
private String name;
private String description;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "join_category_product", joinColumns = {#JoinColumn(name = "category_id", referencedColumnName = "category_id")},
inverseJoinColumns = {#JoinColumn(name = "product_id", referencedColumnName = "product_id")})
private List<Product> products=new ArrayList<>();
#Transient
private MultipartFile image;
Controller:
#GetMapping("/productList")
public String productList(Model model) {
List<Product> product = productService.getProducts();
model.addAttribute("products",product);
return "productList";
You need to make sure that the Thymeleaf can understand the scope of your variables. In your post, you have category.name outside of the for loop. If categories is a property of product, you can do something like:
<tr th:each="product : ${products}">
<td th:text="${product.name}"></td>
<td th:text="${product.price}"></td>
<td>
<th:block th:each="category : ${product.categories}">
<th:block th:text="${category.name}">[category name]</th:block>
<br>
</th:block>
</td>
<td th:text="${product.description}"></td>
<td th:text="${product.shippingWeight}"></td>
<td th:text="${product.quantity}"></td>
<td>delete</td>
</tr>
If a product doesn't have a category, note that the above will still create a <td>. This is likely what you want.
Aside: it would also make sense to supply default values between your tags. This way, you can open up the file directly in a browser (without a container) and still see how it would lay out. This is a huge reason to use Thymeleaf. I included this with [category name] example above.
Otherwise, you can do the shorter version:
<td>[[${product.name}]]</td>

java spring mvc many to many

I'm trying to make a many-to-many example app with spring mvc and hibernate.
I have 2 classes, book and author. I've mapped these 2 class created all relations, but the problem is I can't add values to my join table.
Where's the problem?
CREATE TABLE author
(
author_id serial NOT NULL,
author_name character(100),
CONSTRAINT author_pkey PRIMARY KEY (author_id)
)
CREATE TABLE book
(
book_id serial NOT NULL,
book_name character(50) NOT NULL,
price integer NOT NULL,
CONSTRAINT book_pkey PRIMARY KEY (book_id)
)
CREATE TABLE book_author
(
book_id integer NOT NULL,
author_id integer NOT NULL,
CONSTRAINT book_author_pkey PRIMARY KEY (book_id, author_id),
CONSTRAINT book_author_author_id_fkey FOREIGN KEY (author_id)
REFERENCES author (author_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT book_author_book_id_fkey FOREIGN KEY (book_id)
REFERENCES book (book_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
and my java files
#Entity
#Table(name = "book")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int book_id;
#Column
private String book_name;
#Column
private int price;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "book_author",
joinColumns = { #JoinColumn(name = "book_id")},
inverseJoinColumns = { #JoinColumn(name = "author_id") }
)
private Set<Author> authors = new HashSet<Author>();
//geters and setters
}
Author.java
#Entity
#Table(name="author")
public class Author {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="author_id")
private int author_id;
#Column
private String author_name;
#ManyToMany(mappedBy = "authors")
private Set<Book> books = new HashSet<Book>();
//getters and setters
}
BookDAOImpl.java
#Repository
public class BookDAOImpl implements BookDAO{
#Autowired
private SessionFactory sessionFactory;
public void addBook(Book book) {
sessionFactory.getCurrentSession().saveOrUpdate(book);
}
}
BookServiceImpl.java
#Service
#Transactional
public class BookServiceImpl implements BookService{
#Autowired
private BookDAO bookDAO;
#Override
public void addBook(Book book) {
bookDAO.addBook(book);
}
}
BookController.java
#Controller
#SessionAttributes("authors")
public class BookController {
#Autowired
private BookService bookService;
#Autowired
private AuthorService authorService;
#RequestMapping(value = "/newBook", method = RequestMethod.GET)
public ModelAndView newBook(ModelAndView model) {
Book book = new Book();
model.addObject("book", book);
model.setViewName("bookForm");
return model;
}
#RequestMapping(value = "/saveBook", method = RequestMethod.POST)
public ModelAndView saveBook(#ModelAttribute Book book,BindingResult result)
{
if (book.getBook_id() == 0) {
// if employee id is 0 then creating the
// employee other updating the employee
bookService.addBook(book);
} else {
bookService.updateBook(book);
}
return new ModelAndView("redirect:/newBook");
}
#ModelAttribute("authors")
public List<Author> getAuthors(){
return authorService.getAuthors();
}
}
and finally here is bookForm.jsp file
<body>
<div align="center">
<h1>New/Edit Book</h1>
<form:form action="saveBook" method="post" modelAttribute="book">
<table>
<form:input type="hidden" path="book_id"/>
<tr>
<td>Name:</td>
<td><form:input path="book_name" /></td>
</tr>
<tr>
<td>Price:</td>
<td><form:input path="price" /></td>
</tr>
<tr>
<td>Author:</td>
<td><form:select path="authors" items="${authors}" itemValue="author_id" itemLabel="author_name"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
</div>
</body>
After the page opens, I enter some book name and price and choose an author and click the Save button. It saves book but not saves the join table book_author.
As you can see I can send author_id from uipng
And I can insert book object to database

Resources