NullPointerException in JSF Converter - jsf

I have a table Users and Specializations in database
Users:
CREATE TABLE IF NOT EXISTS `ePrzychodnia`.`users` (
`id` INT NOT NULL AUTO_INCREMENT ,
`firstName` VARCHAR(45) NOT NULL ,
`lastName` VARCHAR(45) NOT NULL ,
`specialization_id` INT NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `personalId_UNIQUE` (`personalId` ASC) ,
INDEX `fk_users_specializations1_idx` (`specialization_id` ASC) ,
CONSTRAINT `fk_users_specializations1`
FOREIGN KEY (`specialization_id` )
REFERENCES `ePrzychodnia`.`specializations` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Specializations:
CREATE TABLE IF NOT EXISTS `ePrzychodnia`.`specializations` (
`id` INT NOT NULL ,
`name` VARCHAR(45) NOT NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `name_UNIQUE` (`name` ASC) )
ENGINE = InnoDB;
Entity class:
Users:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "firstName")
private String firstName;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "lastName")
private String lastName;
#Basic(optional = false)
#JoinColumn(name = "specialization_id", referencedColumnName = "id")
#ManyToOne
private Specialization specializationId;
Specialization:
public class Specialization implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "name")
private String name;
#OneToMany(mappedBy = "specializationId")
private Collection<User> userCollection;
and I try create converter to one select menu in JSF:
SelectOneMenu:
<h:outputLabel for="specialization" value="#{msg.specialization}"/>
<p:selectOneMenu id="specialization" value="#{userMB.user.specializationId}" effect="fade" style="width:200px" converter="specializationConverter">
<f:selectItems value="#{specializationMB.allSpecialization}" var="specialization" itemValue="#{specialization}" itemLabel="#{specialization.name}"/>
</p:selectOneMenu>
<p:message for="specialization"/>
and Converter:
public class SpecializationConverter implements Converter{
private SpecializationDao specializationDao = new SpecializationDao();
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Integer id = Integer.parseInt(value);
return specializationDao.find(id);
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return ((Specialization) value).getId().toString();
}
}
But convertert dont work;/ I have a error:
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
at pl.Project.dao.SpecializationDao.find(SpecializationDao.java:36)
at pl.Project.converter.SpecializationConverter.getAsObject(SpecializationConverter.java:29)
SpecializationDao:
#Stateless
public class SpecializationDao implements SpecializationDaoLocal {
#PersistenceContext
private EntityManager em;
private Specialization specialization;
public SpecializationDao() {
}
public SpecializationDao(Specialization specialization) {
this.specialization = specialization;
}
#Override
public Specialization find(int specializationId) {
return em.find(Specialization.class, specializationId);
}
#Override
public List<Specialization> findAllSpecialization() {
Query q = em.createNamedQuery("Specialization.findAll");
List<Specialization> specializations = q.getResultList();
return specializations;
}
}

Related

Lombok #EqualsAndHashCode and Jhipster TestUtil.equalsVerifier

I am using Jhipster and Lombok for my Java project.
I removed the entity object equals() and hashcode() method generated by Jhipster and replaced with lombok #EqualsAndHashCode
Originally generated By Jhipster
#Entity
#Table(name = "category")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Size(max = 100)
#Column(name = "name", length = 100)
private String name;
// jhipster-needle-entity-add-field - JHipster will add fields here
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public Category name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Category)) {
return false;
}
return id != null && id.equals(((Category) o).id);
}
#Override
public int hashCode() {
return 31;
}
// prettier-ignore
#Override
public String toString() {
return "Category{" +
"id=" + getId() +
", name='" + getName() + "'" +
"}";
}
}
Modified to use Lombok
#Entity
#Data
#EqualsAndHashCode(callSuper = true)
#Table(name = "category")
public class Category extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Size(max = 100)
#Column(name = "name", length = 100)
private String name;
}
The problem is the test generated by Jhipster below fails. At the last 2 lines of the test
/**
* Verifies the equals/hashcode contract on the domain object.
*/
public static <T> void equalsVerifier(Class<T> clazz) throws Exception {
T domainObject1 = clazz.getConstructor().newInstance();
assertThat(domainObject1.toString()).isNotNull();
assertThat(domainObject1).isEqualTo(domainObject1);
assertThat(domainObject1.hashCode()).isEqualTo(domainObject1.hashCode());
// Test with an instance of another class
Object testOtherObject = new Object();
assertThat(domainObject1).isNotEqualTo(testOtherObject);
assertThat(domainObject1).isNotEqualTo(null);
// Test with an instance of the same class
T domainObject2 = clazz.getConstructor().newInstance();
assertThat(domainObject1).isNotEqualTo(domainObject2); //this fails
// HashCodes are equals because the objects are not persisted yet
assertThat(domainObject1.hashCode()).isEqualTo(domainObject2.hashCode()); //this also fails
}
May I know what is the purpose of the test?
every clazz.getConstructor().newInstance(); object should not be equal with each other? The content of the object is the same. Why not?
every clazz.getConstructor().newInstance(); object should have same hashCode? If so, why lombok #EqualsAndHashCode gives different hashcode?
How can I fix the problem?
*Note that the class extends AbstractAuditingEntity
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#CreatedBy
#Column(name = "created_by", nullable = false, length = 50, updatable = false)
#JsonIgnore
private String createdBy;
#CreatedDate
#Column(name = "created_date", updatable = false)
#JsonIgnore
private Instant createdDate = Instant.now();
#LastModifiedBy
#Column(name = "last_modified_by", length = 50)
#JsonIgnore
private String lastModifiedBy;
#LastModifiedDate
#Column(name = "last_modified_date")
#JsonIgnore
private Instant lastModifiedDate = Instant.now();
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Instant getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public Instant getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Instant lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}

hazelcast not equals predicate searching a collection attribute

I am using a hazelcast map to store an object very similar to the following:
#Entity
#Table(name = "organization")
public class Organization
{
public static final String MAP_NAME = "organizations";
#Id
#Column(name = "organizationId", unique = true, nullable = false, columnDefinition = "VARCHAR(36)")
protected String organizationId = UUID.randomUUID().toString();
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "organizationId")
private Set<RecordKeeperConfig> recordKeeperConfigs;
}
And RecordKeeperConfig is defined like:
#Entity
#Table(name = "recordKeeperConfig")
public class RecordKeeperConfig
{
public static final String MAP_NAME = "recordKeeperConfig";
#Id
#Column(name = "recordKeeperConfigId", unique = true, nullable = false, columnDefinition = "VARCHAR(36)")
protected String recordKeeperConfigId = UUID.randomUUID().toString();
#Column(name = "organizationId", columnDefinition = "VARCHAR(36)")
protected String organizationId;
#Enumerated(EnumType.STRING)
#Column(name = "type", length = 8)
protected RecordKeeperType type;
}
Ultimately I want to get back a Set of all of the Organization objects where there is at least one RecordKeeperConfig. I tried using Predicate.notEqual("recordKeeperConfigs", null) but it produces the following exception:
java.lang.IllegalArgumentException: Cannot use NotEqualPredicate predicate with an array or a collection attribute
Try implementing the logical operation as a transient method in your entity class. Then instead of the collection, construct the Hazelcast predicate on that:
Method:
#javax.persistence.Transient
public boolean isRecordKeeperConfigsNotEmpty() {
return getRecordKeeperConfigs() != null && !getRecordKeeperConfigs().isEmpty();
}
Predicate:
EntryObject e = new PredicateBuilder().getEntryObject();
PredicateBuilder predicate = e.is("recordKeeperConfigsNotEmpty");
Collection<Organization> filteredOrganizations = organizationMap.values(predicate);

Get JSF Drop down value and save to database [duplicate]

This question already has answers here:
How to populate options of h:selectOneMenu from database?
(5 answers)
Closed 7 years ago.
I have two tables into database: Book and Category. Now I want to make page where user can add books into Book table, but with selecting appropriate category from Category table.
I can add book into table but I can not save value category in Book table.
[
As you can see category from Book table is Foreign key with category_id from Category table.
Here are model classes:
Book model
#Entity
#Table(name = "book")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
#NamedQuery(name = "Book.findByBookId", query = "SELECT b FROM Book b WHERE b.bookId = :bookId")})
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "book_id")
private Integer bookId;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "name")
private String name;
#Lob
#Size(max = 65535)
#Column(name = "description")
private String description;
#JoinColumn(name = "category", referencedColumnName = "category_id")
#ManyToOne
private Category category;
public Book() {
}
public Book(Integer bookId) {
this.bookId = bookId;
}
public Book(Integer bookId, String name) {
this.bookId = bookId;
this.name = name;
}
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
#Override
public int hashCode() {
int hash = 0;
hash += (bookId != null ? bookId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Book)) {
return false;
}
Book other = (Book) object;
if ((this.bookId == null && other.bookId != null) || (this.bookId != null && !this.bookId.equals(other.bookId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.biblioteka.app.domen.Book[ bookId=" + bookId + " ]";
}
}
Category model
#Entity
#Table(name = "category")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Category.findAll", query = "SELECT c FROM Category c"),
#NamedQuery(name = "Category.findByCategoryId", query = "SELECT c FROM Category c WHERE c.categoryId = :categoryId")})
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "category_id")
private Integer categoryId;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "name")
private String name;
#Lob
#Size(max = 65535)
#Column(name = "description")
private String description;
#OneToMany(mappedBy = "category")
private Collection<Book> bookCollection;
public Category() {
}
public Category(Integer categoryId) {
this.categoryId = categoryId;
}
public Category(Integer categoryId, String name) {
this.categoryId = categoryId;
this.name = name;
}
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#XmlTransient
public Collection<Book> getBookCollection() {
return bookCollection;
}
public void setBookCollection(Collection<Book> bookCollection) {
this.bookCollection = bookCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (categoryId != null ? categoryId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Category)) {
return false;
}
Category other = (Category) object;
if ((this.categoryId == null && other.categoryId != null) || (this.categoryId != null && !this.categoryId.equals(other.categoryId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.biblioteka.app.domen.Category[ categoryId=" + categoryId + " ]";
}
}
Now I have JSF page where I add bookes to database. I have dropdown lists that loads categories into it. User should select one category and save book to table.
This is code from JSF addBook page.
<p:layoutUnit position="center">
<h:form>
<p:inputText value="#{bookBean.name}" a:placeholder="Ime knjige"></p:inputText><br/>
<p:inputText value="#{bookBean.description}" a:placeholder="Opis knjige"></p:inputText><br/>
<p:selectOneMenu value="#{bookBean.category}">
<f:selectItems value="#{categoryBean.allCategories}" var="c"
itemLabel="#{c.name}" itemValue="#{c.categoryId}"/>
</p:selectOneMenu>
<b/><b/>
<p:commandButton value="Dodaj knjigu" action="#{bookBean.addBook()}"/>
</h:form>
</p:layoutUnit>
As you can see I use selectOneMenu with value bookBean.category and then I am not sure what I need to set as value in selectItems.
This is BookBean code:
#ManagedBean
#ApplicationScoped
public class BookBean {
String name;
String description;
int categoryId;
Category category;
#Inject
public BookEJB bookEJB;
public void addBook(){
Book book = new Book();
book.setName(name);
book.setDescription(description);
book.setCategory(category);
bookEJB.addBook(book);
}
public List<Book> getAllBooks(){
return bookEJB.getAll();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public BookEJB getBookEJB() {
return bookEJB;
}
public void setBookEJB(BookEJB bookEJB) {
this.bookEJB = bookEJB;
}
}
Try this :
<f:selectItems value="#{categoryBean.allCategories}" var="c"
itemLabel="#{c.name}" itemValue="#{c}"/>
Listed item name would be category name and category will be assigned to bookBean.category and this can be set as book category and persisted.
Hope this helps.

Adding a Customer object to a database from a SelectOneMenu

I am trying to create a new order by selecting a customer name from a SelectOneMenu. I am getting a Conversion error setting value for 'null Converter'.
Order.java
#Entity
#Table(name = "order")
public class Order
{
#Id
#Column(name = "ORDER_ID", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private long orderId;
#JoinColumn(name = "PRODUCT_ID", referencedColumnName = "PRODUCT_ID")
private Product product;
#Column(name = "QUANTITY")
private int quantity;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "ORDER_DATE")
private Date orderDate;
#ManyToOne(optional = false)
#JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID")
private Customer customer;
// Getters & Setters
}
newOrder.xhtml
<h:outputLabel value="Customer: "/>
<h:selectOneMenu id="customer" value="#{solController.order.customer}" >
<f:selectItem itemLabel="" itemDisabled="true"/>
<f:selectItems value="#{solController.customerList}" var="customer" id="customerID" itemLabel="#{customer.customerName}" itemValue="#{customer.customerId}" />
</h:selectOneMenu>
SolController.java
#ManagedBean(name = "solController")
#SessionScoped
public class SolController implements Serializable
{
#EJB
private SolEJB solEJB;
private Order order = new Order();
private List<Order> orderList = new ArrayList<Order>();
public String doCreateOrder()
{
order = solEJB.createOrder(order);
orderList = solEJB.findOrders();
return "listOrders.xhtml";
}
// Getters & Setters
}
SolEJB.java
#Stateless
public class SolEJB
{
#PersistenceContext(unitName = "myPU")
private EntityManager em;
public Order createOrder(Order order)
{
em.persist(order);
return order;
}
}

JSF: No validator could be found for type when adding a converter and a validator to a p:selectOneMenu

I'm currently encountering the problem specified above when trying to add a converter and a validator to a single field. I know how these 2 works because I've used them before, but this is the first time I've tried both of them on a single field. Here are my codes:
<p:selectOneMenu id="bussProgram"
value="#{signupWizardBean.subscription.businessProgram}">
<f:converter binding="#{membershipProgramConverter}"></f:converter>
<f:validator binding="#{dropdownValidator}"></f:validator>
<f:selectItems value="#{signupWizardBean.membershipPrograms}"
var="plan" itemValue="#{plan}"
itemLabel="#{plan.description}" />
</p:selectOneMenu>
Converter
#Named
#ApplicationScoped
public class MembershipProgramConverter implements Converter {
#PersistenceContext
private transient EntityManager em;
#Inject
private Logger log;
#Override
public Object getAsObject(FacesContext ctx, UIComponent component,
String value) {
if (StringUtils.isBlank(value) || value.equals("0"))
return null;
return em.find(MembershipProgram.class, new Long(value));
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object o) {
MembershipProgram mp = (MembershipProgram) value;
return mp.getId() != null ? String.valueOf(mp.getId()) : null;
}
}
Validator:
#Named
#ApplicationScoped
public class DropdownValidator implements Validator, Serializable {
private static final long serialVersionUID = -456545939475878299L;
#Inject
private ResourceBundle bundle;
#Inject
private FacesContext facesContext;
#Inject
private Logger log;
#Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
log.debug("[dropship-web] validating value={}", value);
if (value == null) {
FacesMessage msg = new FacesMessage(
bundle.getString("error.requiredField"),
bundle.getString("error.requiredField"));
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
facesContext.addMessage("promoCode", msg);
throw new ValidatorException(msg);
}
}
}
Entity Class:
#Entity
#Table(name = "CRM_MEMBERSHIP_PROGRAMS", uniqueConstraints = #UniqueConstraint(columnNames = { "code" }))
#SequenceGenerator(name = "ID_GENERATOR", sequenceName = "CRM_MEMBERSHIP_PROGRAM_SEQ")
public class MembershipProgram extends BaseEntity {
private static final long serialVersionUID = -7796298586810386239L;
#Size(max = 25)
#Column(name = "CODE", nullable = false)
private String code;
#Size(max = 100)
#Column(name = "DESCRIPTION", nullable = true)
private String description;
public MembershipProgram() {
}
public MembershipProgram(long id, String description) {
setId(id);
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((code == null) ? 0 : code.hashCode());
result = prime * result
+ ((description == null) ? 0 : description.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
MembershipProgram other = (MembershipProgram) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
return true;
}
}
Note that on debug: both the MembershipProgramConverter.getAsObject/getAsString, DropdownValidator.validate methods are called.
I also found out that with or without selected item from the dropdown list, I'm encountering:
.validation.UnexpectedTypeException: HV000030: No validator could be found for type: com.czetsuya.models.membership.MembershipProgram.
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: com.czetsuya.models.membership.MembershipProgram.
Finally I was able to figure out the problem, I've added #Size annotation on the target entity, just removed the #Size:
#Size(max = 25)
#OneToOne(optional = false)
#JoinColumn(name = "BUSINESS_PROGRAM", nullable = false)
private MembershipProgram businessProgram;
When I removed the #Size, the problem was solved but I have encountered a new one, on submit it the form always throw:
Validation Error: Value is not valid
To fixed the Value is not valid, make sure that you have properly implemented Model.equals method. My fault was that I rely on eclipse generate hashcode and equals feature, I failed to notice that it calls the equals method from my BaseEntity.

Resources