Spring Binding List<Object> to Form:checkboxes - java

I can't seem to get my form to bind to the checkboxes control. I read many posts on here and tried a few techniques but no luck. Maybe a fresh set of eyes will help.
my controller:
public String editAccount(#RequestParam("id") String id, Model model) {
model.addAttribute("account", accountService.getAccount(id));
model.addAttribute("allRoles", roleService.getRoles());
return EDIT_ACCOUNT;
}
my jsp:
<form:form action="" modelAttribute="account">
<form:checkboxes items="${allRoles}" path="roles" itemLabel="name" itemValue="id" delimiter="<br/>"/>
</form>
the generated html:
<span><input id="roles1" name="roles" type="checkbox" value="1"/><label for="roles1">User</label></span><span><br/><input id="roles2" name="roles" type="checkbox" value="2"/><label for="roles2">Admin</label></span><span><br/><input id="roles3" name="roles" type="checkbox" value="3"/><label for="roles3">SuperAdmin</label></span<input type="hidden" name="_roles" value="on"/>
I used a second for each loop (not shown) to make sure that the model object contained the roles. It does, yet none of the checkboxes are checked and when I submit the roles object is always empty. Can someone please tell me what I'm missing?
Thanks
EDIT
Sorry just realized it might be helpful to see the account and role objects:
public class Account {
private String username, firstName, lastName, email;
private List<Role> roles;
#NotNull
#Size(min = 1, max = 50)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#NotNull
#Size(min = 1, max = 50)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#NotNull
#Size(min = 1, max = 50)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#NotNull
#Size(min = 6, max = 50)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
public class Role {
private int id;
private String name;
public Role() {}
public Role(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#NotNull
#Size(min = 1, max = 50)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
EDIT #2
Controller Post Method
#RequestMapping(value = "edit", method = RequestMethod.POST)
public String updateAccount(#RequestParam("id") String id, #ModelAttribute("account") #Valid AccountEditForm form, BindingResult result) {
System.out.println("FORM VALUES AFTER: " + form);
return (result.hasErrors() ? EDIT_ACCOUNT : ACCOUNT_REDIRECT);
}
AccountEditForm is the form backing object. When I do a GET I grab an Account object and pass the values into an AccountEditForm before displaying the screen. I will attach the AccountEditForm just for clarity. It is very similiar to the account object. I just happened to seperate my form objects from my model objects.
public class AccountEditForm {
private String username, firstName, lastName, email;
private List<Role> roles = new ArrayList<Role>();
#NotNull
#Size(min = 1, max = 50)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#NotNull
#Size(min = 1, max = 50)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#NotNull
#Size(min = 1, max = 50)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#NotNull
#Size(min = 6, max = 50)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
EDIT #3 Role Property Editor
public class RolePropertyEditor extends PropertyEditorSupport {
private Map<Integer, Role> roleMap = new HashMap<Integer, Role>();
public RolePropertyEditor(List<Role> roleList) {
for (Role r : roleList) roleMap.put(r.getId(), r);
}
public void setAsText(String incomingId) {
Role role = roleMap.get(incomingId);
System.out.println("PROPERTY EDITOR ROLE " + role);
setValue(role);
}
public String getAsText() {
System.out.println("PROPERTY EDITOR ID " + ((Role)getValue()).getId());
return String.valueOf(((Role)getValue()).getId());
}
}
Defined in my controller like:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setAllowedFields(new String[] {
"username", "password", "confirmPassword", "firstName", "lastName", "email", "acceptTerms", "currentPassword"
});
binder.registerCustomEditor(Role.class, new RolePropertyEditor(roleService.getRoles()));
}
EDIT #4 NEW ProeprtyEditor
public class SecurityRolePropertyEditor extends PropertyEditorSupport {
private RoleService roleService;
public SecurityRolePropertyEditor(RoleService roleService) {
this.roleService = roleService;
}
public void setAsText(final String name) {
Role role = roleService.getRoleByName(name);
setValue(role);
}
}

Add an equals method to your Roles entity.
see this answer (Spring MVC Pre Populate Checkboxes): of a similar question for more details.

It seems you are missing implementation equals and hashCode method on your entities.

Related

javax.validation is not working in spring boot RESTful app?

i trying to validate my Model class, which is named user.java, i trying to validate the column to prevent it not empty and the email is should be email format, and i use #RepositoryRestController to create my CRUD api, but how do i do this properly?
here is my user.java :
package com.mechadevapi.mechadev.Models;
import java.util.Date;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import org.springframework.data.annotation.Id;
public class User {
#Id
public String Id;
#NotBlank(message = "is empty")
public String username;
#NotBlank(message = "is empty")
#Email(message = "should be email")
public String email;
#NotBlank(message = "is empty")
public String firstname;
public String lastname;
#NotBlank(message = "is empty")
public String password;
#NotBlank(message = "is empty")
public String level;
#NotBlank(message = "is empty")
public Boolean activation;
public Date entry_time;
public Date last_login;
public String getId() {
return Id;
}
public void setId(String id) {
Id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public Boolean getActivation() {
return activation;
}
public void setActivation(Boolean activation) {
this.activation = activation;
}
public Date getEntry_time() {
return entry_time;
}
public void setEntry_time() {
Date entry_time = new Date();
this.entry_time = entry_time;
}
public Date getLast_login() {
return last_login;
}
public void setLast_login() {
Date last_login = new Date();
this.last_login = last_login;
}
}
and here is my repository, UserRepository.java :
package com.mechadevapi.mechadev.Repository;
import javax.validation.Valid;
import com.mechadevapi.mechadev.Models.*;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
#RepositoryRestResource(collectionResourceRel = "user", path = "user")
#Valid
public interface UserRepository extends MongoRepository<User, String> {
}
when i trying to post the data using postman, which is looked like this :
{
"username" : "admin",
"email" : 123,
"firstname" : "ad",
"lastname" : "min",
"password" : "123456",
"level" : "administrator",
"activation" : true
}
the data still saved, it's like the javax.validation anotation is not working, how do i validate this properly?

DTO returns null when called from a Rest client using spring boot

This is making a spring boot project to maintain the MVC architecture and as well being RestFul. There is a project that is fully working properly using the MVC architecture, I'll like to make it work as well by being called from a Rest client. Posting from the Thymeleaf UI works fine, however, when I try to post from a Rest client all the DTO properties are null. I don't know why. How do I make the posting from the client get all the properties posted?
UserDto
#PasswordMatches
public class UserDto {
#NotNull
#Size(min = 1)
private String firstName;
#NotNull
#Size(min = 1)
private String lastName;
#NotNull
#Size(min = 1)
private String username;
#ValidPassword
private String password;
#NotNull
#Size(min = 1)
private String matchingPassword;
#ValidEmail
#NotNull
#Size(min = 1)
private String email;
private boolean isUsing2FA;
private String statusName;
public String getStatusName() {
return statusName;
}
public void setStatusName(String statusName) {
this.statusName = statusName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(final String email) {
this.email = email;
}
private Integer role;
public Integer getRole() {
return role;
}
public void setRole(final Integer role) {
this.role = role;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(final String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(final String lastName) {
this.lastName = lastName;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
this.password = password;
}
public String getMatchingPassword() {
return matchingPassword;
}
public void setMatchingPassword(final String matchingPassword) {
this.matchingPassword = matchingPassword;
}
public boolean isUsing2FA() {
return isUsing2FA;
}
public void setUsing2FA(boolean isUsing2FA) {
this.isUsing2FA = isUsing2FA;
}
#Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("UserDto [firstName=").append(firstName)
.append(", lastName=").append(lastName)
.append(", username=").append(username)
.append(", password=").append(password)
.append(", matchingPassword=").append(matchingPassword)
.append(", email=").append(email)
.append(", isUsing2FA=").append(isUsing2FA)
.append(", role=").append(role).append("]");
return builder.toString();
}
Rest client call
{
"firstName": "Kehinde",
"lastName": "Adeoya",
"username": "ken4ward",
"email": "kadeoya#oltega.com",
"password": "o201115#Adel",
"matchingPassword": "o201115#Adel",
"statusName": "ROLE_ADMIN"
}
This is the
public User save(UserDto user) {
Set<ConstraintViolation<UserDto>> violations = validator.validate(user);
if (violations.size() > 0) {
throw new BadRequestException();
}
............
This is the controller:
#RequestMapping(value = "/registration", method = RequestMethod.POST )
#ResponseBody
public User registerUserAccount(final UserDto accountDto, final HttpServletRequest request) {
final User registered = userInterface.save(accountDto);
eventPublisher.publishEvent(new OnRegistrationCompleteEvent(registered, request.getLocale(), getAppUrl(request)));
return registered;
}
Error
web - 2019-09-28 19:50:54,552 [http-nio-8081-exec-1] INFO o.a.c.c.C.[.[.[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
web - 2019-09-28 19:50:54,987 [http-nio-8081-exec-1] DEBUG o.b.w.c.RegistrationController - Registering user account with information: UserDto [firstName=null, lastName=null, username=null, password=null, matchingPassword=null, email=null, isUsing2FA=false, role=null]
web - 2019-09-28 19:50:55,049 [http-nio-8081-exec-1] ERROR o.b.w.c.e.RestResponseEntityExceptionHandler - 500 Status Code
j.l.NullPointerException: null
at o.b.s.UserService.save(UserService.java:81)
at o.b.w.c.RegistrationController.registerUserAccount(RegistrationController.java:85)
at j.i.r.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java)
at j.i.r.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at j.i.r.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
... 75 frames truncated

JPARepository searching queries returning null

I am having trouble understanding why my userRepository is returning null even when there is a record like it in my table. I tried doing it with my demo codes and it works but when I try doing it with user Authentication it does not work.
Security Services
#Path("/securityservice")
public class SecurityServices {
private UserRepository userRepo;
// http://localhost:8990/login/securityservice/security
#GET
#Path("security")
#Produces(MediaType.APPLICATION_JSON)
public Response getOrderById(#QueryParam("orderId") int orderID,
#HeaderParam("Authorization") String authString) throws JSONException {
JSONObject json = new JSONObject();
if (isUserAuthenticated(authString)) {
json.put("INFO", "Authorized User!");
return Response.status(200)
.entity(json.toString())
.type(MediaType.APPLICATION_JSON)
.build();
} else {
json.put("ERROR", "Unauthorized User!");
return Response.status(403)
.entity(json.toString())
.type(MediaType.APPLICATION_JSON)
.build();
}
}
private boolean isUserAuthenticated(String authString) {
//authString = Basic 3hfjdksiwoeriounf
String[] authParts = authString.split("\\s+");
//authParts[0] = Basic
//authParts[1] = 3hfjdksiwoeriounf
String authInfo = authParts[1];
byte[] bytes = Base64.getDecoder().decode(authInfo);
String decodedAuth = new String(bytes);
// decodedAuth = dj:1234
String[] credentials = decodedAuth.split(":");
//credentials[0]=dj
//credentials[1]=1234
System.out.println("HELLO"+credentials[0]);
System.out.println("HELLO"+credentials[1]);
User user = userRepo.findByUsername(credentials[0]); //this line returns null
if (user != null) {
return true;
} else {
return false;
}
}
User class (Getters and setters for the JPA Repo)
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name="firstname")
private String firstName;
#Column(name="lastname")
private String lastName;
private String password;
private String username;
#Column(name="accesstype")
private String accessType;
public User() {
super();
}
public User(String firstName, String lastName, String password,
String username, String accessType) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.username = username;
this.accessType = accessType;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAccessType() {
return accessType;
}
public void setAccessType(String accessType) {
this.accessType = accessType;
}
}

Spring MVC form validation does't work for nested complex types

I am implementing a sample Spring MVC Form with Form Validation. I have a complex type Address as bean property for Student form bean. And I have added form validation #NotEmpty for Address bean properties. But the same is not reflecting in the UI. But form validation works for other primitive types of Student form bean.
So, Validation works perfectly for Student form bean but not for nested complex types like Address within Student form bean.
I am trying understand the reason and a fix.
Spring version 4.0+.
Hibernate Validator api:5.2.4
Student POJO:
package com.xyz.form.beans;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
import com.xyz.validators.DateNotEmpty;
import com.xyz.validators.ListNotEmpty;
public class Student {
#Size(min = 2, max = 30)
private String firstName;
#Size(min = 2, max = 30)
private String lastName;
#NotEmpty
private String gender;
#DateNotEmpty
#Past
private Date DOB;
private String email;
private String mobileNumber;
#ListNotEmpty
private List<String> courses;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date dOB) {
DOB = dOB;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public List<String> getCourses() {
return courses;
}
public void setCourses(List<String> courses) {
this.courses = courses;
}
}
Address POJO:
package com.xyz.form.beans;
import org.hibernate.validator.constraints.NotEmpty;
import com.xyz.validators.LongNotEmpty;
public class Address {
#NotEmpty
private String houseNo;
#NotEmpty
private String street;
#NotEmpty
private String area;
#NotEmpty
private String city;
#LongNotEmpty
private Long pin;
public String getHouseNo() {
return houseNo;
}
public void setHouseNo(String houseNo) {
this.houseNo = houseNo;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Long getPin() {
return pin;
}
public void setPin(Long pin) {
this.pin = pin;
}
}
Student Controller:
#RequestMapping(value = "/newStudentDetails.do", method = RequestMethod.POST)
public ModelAndView newStudentDetails(
#Valid #ModelAttribute("student") com.xyz.form.beans.Student studentFormBean,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new ModelAndView("newStudentPage");
}
Student studentDto = new Student();
studentDto.setFirstName(studentFormBean.getFirstName());
studentDto.setLastName(studentFormBean.getLastName());
studentDto.setGender(studentFormBean.getGender());
studentDto.setDOB(new Date(studentFormBean.getDOB().getTime()));
studentDto.setEmail(studentFormBean.getEmail());
studentDto.setMobileNumber(studentFormBean.getMobileNumber());
StringBuilder sb = new StringBuilder();
sb.append(studentFormBean.getAddress().getHouseNo() + ", ");
sb.append(studentFormBean.getAddress().getStreet() + ", ");
sb.append(studentFormBean.getAddress().getArea() + ", ");
sb.append(studentFormBean.getAddress().getCity() + "-");
sb.append(studentFormBean.getAddress().getPin());
studentDto.setAddress(sb.toString());
studentDto.setCourses(studentFormBean.getCourses());
studentDao.createStudent(studentDto);
ModelAndView mav = new ModelAndView("newStudentSuccess");
return mav;
}
Thanks,
Viswanath
You need to annotate your complex types with #Valid.
This is the reference (which references here)
Hi lets try #ModelAttribute("student") #Valid com.xyz.form.beans.Student studentFormBean in place of #Valid #ModelAttribute("student")
For nested complex types, you have to activate the direct field access. Just like below:
#org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice {
#InitBinder
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.initDirectFieldAccess();
}

JPA Entity being ignored

I'm trying to use JPA for the first time in a project. Most of my entities are working fine, but I am having trouble with one which is part of a Joined Inheritance Strategy.The entities are also being serialised by Jackson so they also have Json annotations.
The parent "User" class:
(Edit: added "Type" field)
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.WRAPPER_OBJECT)
#JsonTypeName("user")
#JsonSubTypes({
#JsonSubTypes.Type(name="customer", value=Customer.class),
#JsonSubTypes.Type(name="employee", value=Employee.class)})
#Entity(name = "User")
#Table(name="user")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.INTEGER)
#NamedQuery(name="User.all",query = "select u from User u")
public abstract class User {
#Id
private String username;
#Column(name = "type",nullable = false)
private int type;
public User(){
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public abstract Set<Order> getOrders();
}
A Child "Employee"
#JsonTypeName("employee")
#Entity(name="Employee")
#Table(name="employee")
#PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
#DiscriminatorValue("1")
#NamedQuery(name = "Employee.all",query = "select e from Employee e")
public class Employee extends User implements Serializable{
private String username;
private String firstName;
private String lastName;
private String email;
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate dateStarted;
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate dateEnded;
#OneToMany(mappedBy = "employee",targetEntity = Order.class,fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
#JsonIgnore
private Set<Order> orders = new HashSet<>();
public Employee() {
}
#Override
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public void addOrder(Order order){
orders.add(order);
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getDateStarted() {
if(dateStarted != null)
return dateStarted.toString();
else return null;
}
public void setDateStarted(LocalDate dateStarted) {
this.dateStarted = dateStarted;
}
public String getDateEnded() {
if(dateEnded != null)
return dateEnded.toString();
else return null;
}
public void setDateEnded(LocalDate dateEnded) {
this.dateEnded = dateEnded;
}
#Override
public String toString(){
return getUsername();
}
}
And a child "Customer":
(Edit: removed #Id field)
#JsonTypeName("customer")
#Entity(name="Customer")
#Table(name="customer")
#PrimaryKeyJoinColumn(name = "username",referencedColumnName = "username")
#DiscriminatorValue("2")
#NamedQueries({
#NamedQuery(name="Customer.all",query = "select c from Customer c")
})
public class Customer extends User implements Serializable{
public enum VIP_TYPE {NORMAL,SILVER,GOLD,DIAMOND}
#Transient
private static final int SILVER_THRESHOLD = 1000;
#Transient
private static final int GOLD_THRESHOLD = 2000;
#Transient
private static final int DIAMOND_THRESHOLD = 3000;
private String firstName;
private String lastName;
private String email;
private String address;
private String postcode;
private String mobileNumber;
private String homeNumber;
#Convert(converter = VipTypeConverter.class)
private VIP_TYPE vipGroup;
private String discount;
#OneToMany(mappedBy = "customer",targetEntity = Order.class,fetch=FetchType.EAGER,cascade = CascadeType.ALL)
#JsonIgnore
private Set<Order> orders = new HashSet<>();
public Customer() {
}
#Override
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public void addOrder(final Order order){
orders.add(order);
updateVipGroup();
}
private void updateVipGroup() {
int sum = orders.stream().map(Order::getPayment).distinct().mapToInt(p->p.getAmmount()).sum();
if(sum > DIAMOND_THRESHOLD){
vipGroup = VIP_TYPE.DIAMOND;
return;
}
if(sum > GOLD_THRESHOLD){
vipGroup = VIP_TYPE.GOLD;
return;
}
if(sum > SILVER_THRESHOLD){
vipGroup = VIP_TYPE.SILVER;
return;
}
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail(String email) {
this.email = email;
}
public void setAddress(String address) {
this.address = address;
}
public void setDiscount(String discount) {
this.discount = discount;
}
public void setVipGroup(VIP_TYPE vipGroup) {
this.vipGroup = vipGroup;
}
public void setHomeNumber(String homeNumber) {
this.homeNumber = homeNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public String getDiscount() {
return discount;
}
public VIP_TYPE getVipGroup() {
return vipGroup;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getAddress() {
return address;
}
public String getPostcode() {
return postcode;
}
public String getMobileNumber() {
return mobileNumber;
}
public String getHomeNumber() {
return homeNumber;
}
}
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="local" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/cod</jta-data-source>
<class>com.technicalpioneers.cod.user.Customer</class>
<class>com.technicalpioneers.cod.user.Employee</class>
<class>com.technicalpioneers.cod.user.User</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
Everything to do with "employee" works file, I can use the named query Employee.all to find all the employees in the database.
However, If I try to retrieve any customers I get errors. If I try to run the named query Customer.all I get:
java.lang.IllegalArgumentException: NamedQuery of name: Customer.all not found.
If I try to use EntityManager's find() method to find a particular customer I get:
javax.servlet.ServletException: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [2] of type [class java.lang.Integer].
Descriptor: RelationalDescriptor(com.technicalpioneers.cod.user.User --> [DatabaseTable(user)])
I don't understand why the Customer entity is not being found by JPA. I've checked the user table and the "type" column is there with correct numbers, and #DescriminatorValue is set correctly. It's almost like the annotations are being ignored?
Have done many clean rebuilds and redeploys too. Any help would be very much appreciated!
I found this eventually. https://bugs.eclipse.org/bugs/show_bug.cgi?id=429992
It turns out EclipseLink will silently ignore entities with lambda expressions! Very annoying for it to not be at least mentioned in logs!
Thanks to everyone who took the time!

Categories

Resources