If else ladder in Spring and Hibernate using JSP - java

I'm trying to implement the filter in two fields i.e. category and itemBrand by using Spring, Hibernate and JSP. The scenario is if I pass category then it will return the records of that category or if I pass the itemBrand the it will return the records of that itemBrand and if I pass both category and itemBrand then it will return the records in combination of both and if I pass nothing that means both the fields (category and itemBrand) are empty the it will return all the record from that table.
But I'm getting the below while implementing it.
Can anyone help me out for this ?
Type Exception Report
Message Request processing failed; nested exception is java.lang.IllegalArgumentException: Unknown parameter name : category
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Unknown parameter name : category
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.IllegalArgumentException: Unknown parameter name : category
org.hibernate.query.internal.QueryParameterBindingsImpl.getBinding(QueryParameterBindingsImpl.java:208)
org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:486)
org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:104)
grocery.stock.managment.dao.AdminDaoImpl.searchByCategory(AdminDaoImpl.java:148)
grocery.stock.managment.services.AdminServiceImpl.searchByCategory(AdminServiceImpl.java:125)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
com.sun.proxy.$Proxy75.searchByCategory(Unknown Source)
grocery.stock.managment.controller.MainController.itemFilter(MainController.java:238)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
Below is the form
<form class="mg-b-20" action="itemFilter" method="post">
<div class="row gutters-8">
<div class="col-3-xxxl col-xl-3 col-lg-4 col-12 form-group">
<input type="text" placeholder="Search by Category"
name="category" class="form-control">
</div>
<div class="col-3-xxxl col-xl-3 col-lg-4 col-12 form-group">
<input type="text" placeholder="Search by Brand" name="itemBrand"
class="form-control">
</div>
<div class="col-1-xxxl col-xl-2 col-lg-3 col-12 form-group">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</div>
</form>
Below is the Main Controller's code
#PostMapping("itemFilter")
public ModelAndView itemFilter(#RequestParam("category") String category,
#RequestParam("itemBrand") String itemBrand) {
ModelAndView modelAndView = new ModelAndView("allitems");
if (itemBrand == "") {
List<Item> items = adminService.searchByCategory(category);
modelAndView.addObject("items", items);
} else if (category == "") {
List<Item> items = adminService.searchByItemBrand(itemBrand);
modelAndView.addObject("items", items);
} else if (category == "" || category == null && itemBrand == "" || itemBrand == null) {
List<Item> items = adminService.getAllItems();
modelAndView.addObject("items", items);
} else {
List<Item> items = adminService.searchByCategoryAndItemBrand(category, itemBrand);
modelAndView.addObject("items", items);
}
return modelAndView;
}

Don't use those constructs and especially not in a controller (it belongs in the service). Instead, create a single service method that dynamically creates a query (or Criteria API) based on those parameters.
#Service
#Transactional
public class AdminService {
#PersistenceContext
private EntityManager em;
public List<Item> search(String category, String itemBrand) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<item> cq = cb.createQuery(Item.class);
Root<Item> c = cq.from(Item.class);
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.hasText(category) {
predicates.add(cb.equals(c.get("category", category)));
}
if (StringUtils.hasText(itemBrand) {
predicates.add(cb.equals(c.get("itemBrand", itemBrand)));
}
cq = cq.where(predicates.toArray(new Predicate[0]{});
return em.getCriteriaQuery(cq).getResultLlist();
}
}
Something along these lines will do the trick (from the top of my head, so it might need some work). Adding an additional criteria is now a simple matter of checking for a value and add it to the list.
When generating a JPA metamodel you could even make it less error-prone by replacing the c.get("category") etc. with safer constructs.

Related

SQL Error: 1364, SQLState: HY000 - Field 'rating_id' doesn't have a default value / When saving a child entity with one-to-one relation

I have two entities with a one-to-one bidirectional relation.
The parent entity:
package com.pierre.inventorymanager.model;
import lombok.*;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Getter
#NoArgsConstructor
public class Rating {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
private Float rate;
#Column(name = "review_left")
private boolean reviewLeft;
#OneToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "review_id", referencedColumnName = "id")
private Review review;
public void setProduct(Product product) {
Product oldProduct = this.product;
if (Objects.equals(product, oldProduct))
return;
this.product = product;
if (oldProduct != null)
oldProduct.removeRating(this);
if (product != null)
product.addRating(this);
}
public void setRate(Float rate) {
this.rate = rate;
}
public void setReviewLeft(boolean reviewLeft) {
this.reviewLeft = reviewLeft;
}
public void setReview(Review review) {
Review oldReview = this.review;
if (Objects.equals(review, oldReview))
return;
this.review = review;
if (oldReview != null)
oldReview.setRating(null);
if (review != null)
review.setRating(this);
}
#Override
public String toString() {
return "Rating " + id + " : [productID = " + product.getId() + ", rate = " + rate +
", reviewLeft = " + reviewLeft + ", review = " + review + "]";
}
}
The corresponding MySQL table:
CREATE TABLE IF NOT EXISTS inventory.rating
(
`id` INT NOT NULL AUTO_INCREMENT,
`product_id` INT NOT NULL,
`review_id` INT,
`rate` INT,
`review_left` BOOLEAN NOT NULL,
PRIMARY KEY (id)
);
The child entity:
package com.pierre.inventorymanager.model;
import lombok.*;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Getter
#NoArgsConstructor
public class Review {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToOne(mappedBy = "review", cascade = CascadeType.PERSIST)
private Rating rating;
private String title;
private String body;
public void setRating(Rating rating) {
Rating oldRating = this.rating;
if (Objects.equals(rating, oldRating))
return;
this.rating = rating;
if (oldRating != null)
oldRating.setReview(null);
if (rating != null)
rating.setReview(this);
}
public void setTitle(String title) {
this.title = title;
}
public void setBody(String body) {
this.body = body;
}
#Override
public String toString() {
return "Review " + id + " : [ratingID = " + rating.getId() + ", title = " + title +
", body = " + body.substring(0, Math.min(body.length(), 10)) + "]";
}
}
Its table:
CREATE TABLE IF NOT EXISTS inventory.review
(
`id` INT NOT NULL AUTO_INCREMENT,
`rating_id` INT NOT NULL,
`title` VARCHAR(45) NOT NULL,
`body` TEXT NOT NULL,
PRIMARY KEY (id)
);
I'm retrieving the values of both entities through this form using Thymeleaf as template:
<form class="user" action="#" th:action="#{/product/{id}/product_rated(id = ${product.id})}"
th:object="${rating}" method="post">
<div class="form-group row">
<div class="col-sm-3">
<p>Rate Product:</p>
</div>
<div class="slider-container col-sm-3">
<input th:field="*{rate}" type="range" min="1" max="5" step="1" value="3"
class="slider" id="myRange"/>
</div>
</div>
<div class="form-group row">
<div class="custom-control custom-checkbox small">
<input th:field="*{reviewLeft}" type="checkbox"
class="custom-control-input" id="customCheck"
onchange="document.getElementById('inputTitle').disabled = !this.checked;
document.getElementById('inputBody').disabled = !this.checked;"/>
<label class="custom-control-label" for="customCheck">Leave Review</label>
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
<input th:field="*{review.title}" type="text" disabled
class="form-control form-control-user"
id="inputTitle" placeholder="Title for your review"/>
</div>
</div>
<div class="form-group row">
<div class="col-sm-3">
<textarea th:field="*{review.body}" class="form-control rounded-0" rows="10"
id="inputBody" placeholder="Tell us what you think.." disabled>
</textarea>
</div>
</div>
<div class="form-group row">
<button type="submit" class="btn btn-primary btn-user btn-block col-sm-3">
Submit
</button>
</div>
</form>
Controller methods:
#GetMapping(value = "/product/{id}/rate_product")
public String rateProduct(#PathVariable("id") long id, Model model) {
model.addAttribute("rating", new Rating());
model.addAttribute("product", service.getProductByID(id));
return "rate_product";
}
#PostMapping(value = "/product/{id}/product_rated")
public String saveProductRating(#PathVariable("id") long id, #ModelAttribute("rating") Rating rating) {
service.saveRating(rating, id);
return "redirect:/";
}
When trying to call this method in my Service, neither parent nor child get saved and the exception is thrown:
public void saveRating(Rating rating, long id) {
Product product = productRepository.getById(id);
rating.setProduct(product);
ratingRepository.save(rating);
}
2021-03-21 12:33:47.507 WARN 5448 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1364, SQLState: HY000
2021-03-21 12:33:47.507 ERROR 5448 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : Field 'rating_id' doesn't have a default value
2021-03-21 12:33:47.531 ERROR 5448 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement] with root cause
java.sql.SQLException: Field 'rating_id' doesn't have a default value
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025) ~[mysql-connector-java-8.0.23.jar:8.0.23]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-4.0.2.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.2.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3200) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3806) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:720) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:706) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~
.
.
.
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.5-20210315.181825-80.jar:5.3.5-SNAPSHOT]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.5-20210315.181825-80.jar:5.3.5-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.43.jar:9.0.43]
at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
At first I thought the problem was because I'm trying to save both entities at the same time when neither had any id in the tables, so I changed the code to:
public void saveRating(Rating rating, long id) {
Product product = productRepository.getById(id);
rating.setProduct(product);
Review review = rating.getReview();
rating.setReview(null);
ratingRepository.save(rating);
review.setRating(rating);
reviewRepository.save(review);
}
With the above code, saving the parent Rating works fine, the problem occurs when hibernate tries to save the child Review. I tried all CascadeTypes on either and both entities and both FetchTypes and nothing seems to work. I also tried GenerationType.AUTO and didn't work either. Dropping the database also didn't work.
application.properties:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.url=jdbc:mysql://localhost:3306/inventory?allowMultiQueries=true&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=pass
spring.datasource.initialization-mode=always
spring.datasource.separator=^;
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.jpa.properties.hibernate.format_sql=true
Changing ddl mode to create and update didn't yield any results.
Note
A Rating should be able to exist without a Review (a user rates the product without leaving a review) but a Review should always have a parent Rating. That's the intended behaviour I'm trying to achieve.
I'm sorry I was wrong.
You don't need the rating_id because you are using review_id on the rating table for that purpose already.
So you can delete rating_id on the review table.

An error happened during template parsing (template: "class path resource [templates/index.html]")

I'm trying to open my html page but I'm stuck with these error whenever I try to get access to localhost.
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Aug 11 18:24:14 CEST 2020
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/index.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/index.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "index" - line 9, col 36)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
... 48 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "index" - line 9, col 36)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleStandaloneElementEnd(TemplateHandlerAdapterMarkupHandler.java:260)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:256)
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleStandaloneElementEnd(OutputExpressionInlinePreProcessorHandler.java:169)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:104)
at org.attoparser.HtmlElement.handleStandaloneElementEnd(HtmlElement.java:79)
at org.attoparser.HtmlMarkupHandler.handleStandaloneElementEnd(HtmlMarkupHandler.java:241)
at org.attoparser.MarkupEventProcessorHandler.handleStandaloneElementEnd(MarkupEventProcessorHandler.java:327)
at org.attoparser.ParsingElementMarkupUtil.parseStandaloneElement(ParsingElementMarkupUtil.java:96)
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:706)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
... 50 more
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'fullName' of bean class [com.example.demo.domain.User]: Bean property 'fullName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:622)
at org.springframework.beans.AbstractNestablePropertyAccessor.getPropertyValue(AbstractNestablePropertyAccessor.java:612)
at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:104)
at org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:228)
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:129)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:258)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227)
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
... 63 more
I will attach the files involved:
Home controller:
#Controller
public class HomeController {
#RequestMapping("/")
public String home(Model model) {
model.addAttribute("formData", new User());
return "index";
}
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String processFormData(User user) {
return "results";
}
}
User domain class:
public class User {
private String fullName;
private int age;
private boolean employed;
private String gender;
public User() {}
public User(String full_name, int age, boolean employed, String gender) {
super();
this.fullName = full_name;
this.age = age;
this.employed = employed;
this.gender = gender;
}
// GETTER AND SETTERS HERE
}
index.html:
<!doctype html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8" />
<title>Home page</title>
</head>
<body>
<form action="/create" method="POST" th:object="${formData}">
<p>Full name: <input type="text" th:field="${formData.fullName}" /></p>
<p>Age: <input type="text" th:field="${formData.age}" /></p>
<p>Employed: <input type="checkbox" th:field="${formData.employed}" th:value="true"/></p>
<p>
Gender: <br>
Male <input type="radio" th:field="${formData.gender}" th:value="Male" />
Female <input type="radio" th:field="${formData.gender}" th:value="Female" />
</p>
<p>
<input type="submit" value="Submit"/>
<input type="reset" value="Reset"/>
</p>
</form>
</body>
</html>
Invalid property 'fullName' of bean class [com.example.demo.domain.User]: Bean property 'fullName' is not readable or has an invalid getter method
Thymeleaf can only access the properties of objects via getters. Also if you were to use object binding with Thymeleaf you would have to make sure you have setters and default constructor.
In general whenever you work with Thymeleaf it is a good idea to define all the getters, setters and default constructor for all objects being passed to thymeleaf.
you should change the visibility of the user's properties to public.
and it's done.
greetings from El salvador

Spring boot:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'edit' available as request attribute

I'm working on my "Edit" site,which can change the data on the existing webpage.
I'm getting this error and can't find the problem on my code.
My controller:
#PostMapping("editKursInfo")
public String editKursInfo(Model model,
#Valid #ModelAttribute("edit") Kurs kurs,
BindingResult bindingresult)
{
if (bindingresult.hasErrors()) {
model.addAttribute("edit", kurs);
return "editKursInfo";
}
model.addAttribute("kurs", kurs);
// model.addAttribute("edit", kurs);
data.saveKurs(kurs);
return "editKurs";
}
Thymeleaf:
<form action="editKursInfo" method="POST"
th:object="${edit}">
<span th:text="${kurs.kursName}" id="kursNameSpan" style=" display: none;"></span>
<input th:field="*{kursName}"
type="text"
align="left"
class="form-control"
style="width:250px;"
th:errorclass="is-invalid"
id="kursNameInput"
value=""/><br>
<div th:if="${#fields.hasErrors('kursName')}" th:errors="*{kursName}" class="invalid-feedback"> </div>
Javascript:
<script type="text/javascript">
var value = $("#kursNameSpan").text();
var lower = $("#kursNameInput").val(value);
</script>
the part of error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'edit' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.checkErrors(FieldUtils.java:212) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.util.FieldUtils.hasErrors(FieldUtils.java:71) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.expression.Fields.hasErrors(Fields.java:58) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
You have to set the edit attribute on the model before actually showing the page. So you need to have a GET-mapped method, something like the following:
#GetMapping(value = "/editKursInfo")
public String viewEditKursPage(Model model) {
Kurs kurs = new Kurs();
model.addAttribute("edit", kurs);
return "editKursInfo";
}

Java Play 2.3.8: DataSource user is null? bindFromRequest() does not work properly

I started learning Play this week. Now I am trying to write a Code that creates a session, when a user logs in.
Sorry, but the post looks a bit messy because I am new user, who is not allowed to post pictures.
I am using Java play 2.3.8 and eclipse 4.4.1 (and I already tried the other tips i saw here)
At the moment I always get this errormessage:
play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.reflect.InvocationTargetException]]
at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.6.jar:2.3.6]
at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.6.jar:2.3.6]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.6.jar:2.3.6]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$4.apply(PlayDefaultUpstreamHandler.scala:320) [play_2.11-2.3.6.jar:2.3.6]
at scala.Option.map(Option.scala:145) [scala-library-2.11.1.jar:na]
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at play.data.Form.bind(Form.java:394) ~[play-java_2.11-2.3.6.jar:2.3.6]
at play.data.Form.bindFromRequest(Form.java:221) ~[play-java_2.11-2.3.6.jar:2.3.6]
at controllers.Application.authenticate(Application.java:70) ~[classes/:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$11$$anonfun$apply$11.apply(routes_routing.scala:209) ~[classes/:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$11$$anonfun$apply$11.apply(routes_routing.scala:209) ~[classes/:na]
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_31]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_31]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_31]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_31]
at play.data.Form.bind(Form.java:391) ~[play-java_2.11-2.3.6.jar:2.3.6]
Caused by: java.lang.RuntimeException: DataSource user is null?
at com.avaje.ebeaninternal.server.lib.sql.DataSourcePool.(DataSourcePool.java:204) ~[avaje-ebeanorm-3.3.4.jar:na]
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.getDataSourceFromConfig(DefaultServerFactory.java:419) ~[avaje-ebeanorm-3.3.4.jar:na]
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.setDataSource(DefaultServerFactory.java:385) ~[avaje-ebeanorm-3.3.4.jar:na]
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:163) ~[avaje-ebeanorm-3.3.4.jar:na]
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:125) ~[avaje-ebeanorm-3.3.4.jar:na]
This is my method, that is called:
public static Result authenticate() {
Form<Login> loginForm = Form.form(Login.class);
Login loginUser = loginForm.bindFromRequest().get();
if (!usersList.getUsers().contains(loginForm)) {
return ok(login.render("test"));
} else {
session().clear();
session("email", loginForm.get().email);
System.out.println("ich bin hier");
return redirect(routes.Application.login());
}
}
This is the model (getters and setters are there, too):
public class Login {
public Login(){
}
public String email;
public String password;
public Login(String email, String password){
this.email=email;
this.password=password;
}
public String validate() {
if (Users.authenticate(email, password) == null) {
return "Invalid user or password";
}
return null;
}
public static Finder<String,Login> find = new Finder<String,Login>(
String.class, Login.class
);
And here the scala.html document:
<div class="Login">
<br>
<br>
<br>
<br>
<h1>Login</h1>
<form action="#routes.Application.authenticate()" method="post">
<p><input type="email" name="email" placeholder="Email" value=""></p>
<p><input type="password" name="password" placeholder="Password" value=""></p>
<p class="submit"><input type="submit" name="Login" value="Login"></p>
</form>
And last but not least the error message in my browser says the exception is thrown in line 70:
[RuntimeException: java.lang.reflect.InvocationTargetException]
System.out.println("nach loginform");
68
69 //System.out.println(loginForm.bindFromRequest().toString());
70 Login loginUser = loginForm.bindFromRequest().get();
71
72 System.out.println(loginForm.toString());
73// Form loginForm = form(Login.class).bindFromRequest();
74
75 if (!usersList.getUsers().contains(loginForm)) {
thanks in advance for helping me with this issue
Are you missing something
#Entity
public class Login extends Model {
and also check if ebean.default="models.*" line is uncommented in application.conf

JSF and ManagedBean : NullPointerException [duplicate]

This question already has an answer here:
Caused by: javax.naming.NameNotFoundException - Name [Class/object] is not bound in this Context
(1 answer)
Closed 9 years ago.
I'm designing a JSF application with managed beans.
For the moment, I've only been trying to create a simple login page (username and password are hard-coded for the moment) :
<h:form class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2><hr />
<input name="username" type="text" class="input-block-level" placeholder="Username" />
<input name="password" type="password" class="input-block-level" placeholder="Password" />
<h:commandButton action="#{userController.login}" class="btn btn-block btn-primary" type="submit" value="Sign in" />
</h:form>
Here is the controller (UserController.java) :
#ManagedBean(name="userController")
#ApplicationScoped
public class UserController {
#EJB
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public UserController() {
}
public void login() throws IOException {
Boolean login = userService.login("admin", "p4ssw0rd");
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
if (login == true) {
externalContext.redirect("dashboard.xhtml");
} else {
externalContext.redirect("login.xhtml");
}
}
}
And this is the UserService.java file :
#Stateless
public class UserService {
#PersistenceContext
private EntityManager em;
public static String md5(String input) {
// Removed for clarity...
}
public Boolean login(String username, String password) {
//String hash = md5(password);
return Boolean.TRUE; // As you can see, nothing can fail for the moment
}
}
When I submit the login form, a NullPointerException shows up :
javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.NullPointerException
at com.myname.myproject.managedbean.UserController.login(UserController.java:33)
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)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 24 more
In UserController.java, if I replace this line :
Boolean login = userService.login("admin", "p4ssw0rd");
By this one :
Boolean login = true; // Or false (I've tested twice)
Everything works OK, so it seems like Java fails to find the UserService...
Thanks for your help, I'm completely lost.
Did you check putting getters and setters in your managed bean called UserController?
If you did not, even if the code compiles correctly, dependency injection would not be held correctly.
I believe that the problem is the EJB. It should be annotated #LocalBean if it is no-interface bean or implement an interface otherwise. Try something like this:
#Stateless
public class UserService implements UserServiceLocal {
#Override
public boolean login () {
//dummy implementation
return true;
}
}
where UserServiceLocal is:
#Local
public interface UserServiceLocal {
public boolean login();
}
Usage:
#ManagedBean(name="userController")
#ApplicationScoped
public class UserController {
#EJB
private UserServiceLocal userService;
public void login() {
userService.login();
}
}
Regarding your question about why it should implement an interface, please see EJB's - when to use Remote and/or local interfaces?. An EJB (enterprise java bean) can have an interface (which can be annotated with #Remote, meaning that the bean who implements it runs in a distributed environment, or annotated with #Local meaning the bean runs inside the same JVM. In contrast, a no-interface bean is a bean that does not implements any interface. Therefore, you should instruct JVM to treat it as a bean instead of a POJO (plain old java object); this can be accomplished by adding #LocalBean annotation on the class that it is supposed to be your bean /EJB.

Categories

Resources