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;
}
}
Related
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.
I'm new to JSF, and stuck in a problem.
I have a selectOneMenu for displaying the list of countries. When the user selects one of the country, there's another selectOneMenu having the cities (=regions in my case) should be auto-populated.
I tried several iterations for doing the same but didn't help.
Please let me know if anything else is also needed to help me. Would really appreciate it.
UPDATE:
Here's the code after adding listener:
<p:outputLabel for="countryRegistration">#{msg['country']}:</p:outputLabel>
<p:selectOneMenu id="countryRegistration" value="#{mbcActor.geoData.country}" style="width:120px;" >
<f:attribute name="country" value="java.util.List" />
<f:converter converterId="ViewScopedObjectConverter"/>
<f:selectItem itemLabel="#{msg['selectCountry']}" itemValue=""/>
<f:selectItems value="#{geoLists.countryList}" var="country" itemLabel="#{country.name}"/>
<p:ajax listener="#{mbcActor.geoData.updateRegions}" render="cityRegistration"/>
</p:selectOneMenu>
<p:message for="countryRegistration"/>
<p:outputLabel for="cityRegistration">#{msg['city']}:</p:outputLabel>
<p:selectOneMenu id="cityRegistration" value="#{mbcActor.geoData.region}" style="width:120px;">
<f:attribute name="regions" value="java.util.List" />
<f:converter converterId="ViewScopedObjectConverter"/>
<f:selectItem itemLabel="#{msg['selectCity']}" itemValue=""/>
<!--<f:selectItems value="#{geoLists.regionForCountry}" var="region" itemLabel="#{region.name}"/>-->
<f:selectItems value="#{geoLists.getRegionForCountry(country)}" var="region" itemLabel="#{region.description}"/>
</p:selectOneMenu>
<p:message for="cityRegistration"/>
But it says:
Oct 05, 2013 2:04:53 AM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: Target Unreachable, identifier 'mbcActor' resolved to null
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'mbcActor' resolved to null
at org.apache.el.parser.AstValue.getTarget(AstValue.java:98)
at org.apache.el.parser.AstValue.invoke(AstValue.java:259)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processCustomListener(AjaxBehaviorListenerImpl.java:70)
at org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processArgListener(AjaxBehaviorListenerImpl.java:59)
at org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxBehaviorListenerImpl.java:47)
Beans:
package xxx.core.entities;
// Generated Oct 20, 2009 11:07:18 AM by Hibernate Tools 3.2.2.GA
import javax.faces.event.ValueChangeEvent;
import javax.inject.Inject;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import static javax.persistence.GenerationType.IDENTITY;
/**
* DataActorGeo
*/
#Entity
#Table(name = "dataActorGeo")
// #org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#Access(AccessType.PROPERTY)
public class DataActorGeo implements java.io.Serializable {
private Integer id;
private Country country;
private Region region;
private String city;
private String province;
private String address;
private String addressLine2;
private String postCode;
private String nationality;
private String phone1;
private String phone2;
private Double latitude;
private Double longitude;
private Actor actor;
private List<Region> regions;
#Inject
EntityManager entityManager;
public void updateRegions() {
//Country ctry = (Country) event.getNewValue();
try{
System.out.println("bbbbbbbbbbbbbbbbbbbbbbb" + country.toString());
// if (regions == null) {
this.regions = entityManager.createQuery("select r From Region r Where r.country.id = :countryId order by r.description ")
.setParameter("countryId", country.getId())
.getResultList();
//countryIdCache = country.getId();
// }
System.out.println("aaaaaaaaaaa" + regions.toString());
} catch(Exception e){System.out.println("cccccccccc"); }//return new ArrayList<Region>(); }
//return regions;
}
public DataActorGeo() {
}
public DataActorGeo(Country country, String city) {
this.country = country;
this.city = city;
}
public DataActorGeo(Country country, Region region, String city, String address, String postCode, String phone1, String phone2, Actor actor) {
this.country = country;
this.region = region;
this.city = city;
this.address = address;
this.postCode = postCode;
this.phone1 = phone1;
this.phone2 = phone2;
this.actor = actor;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "Country")
// #IndexedEmbedded(prefix = "country.")
public Country getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "Region")
// #IndexedEmbedded(prefix = "region.")
public Region getRegion() {
return this.region;
}
public void setRegion(Region region) {
this.region = region;
}
public List<Region> getRegions()
{
return this.regions;
}
public void setRegions(List<Region> regions)
{
this.regions=regions;
}
#Column(name = "City")
// //#Field(index = Index.UN_TOKENIZED)
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
#Column(name = "province")
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
#Column(name = "address")
// //#Field(index = Index.TOKENIZED)
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "addressLine2")
// //#Field(index = Index.TOKENIZED)
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
#Column(name = "postCode")
// //#Field(index = Index.UN_TOKENIZED)
public String getPostCode() {
return this.postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
#Column(name = "nationality")
// //#Field(index = Index.UN_TOKENIZED)
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
#Column(name = "phone1")
// //#Field(index = Index.UN_TOKENIZED)
public String getPhone1() {
return phone1;
}
public void setPhone1(String phone1) {
this.phone1 = phone1;
}
#Column(name = "phone2")
// //#Field(index = Index.UN_TOKENIZED)
public String getPhone2() {
return phone2;
}
public void setPhone2(String phone2) {
this.phone2 = phone2;
}
#OneToOne(mappedBy = "geoData")
public Actor getActor() {
return actor;
}
public void setActor(Actor actor) {
this.actor = actor;
}
#Column(name = "latitude")
public Double getLatitude() {
return latitude;
}
#Column(name = "longitude")
public Double getLongitude() {
return longitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
}
package xxx.lists;
import xxx.application.configuration.ISNetApp;
import xxx.core.entities.Country;
import xxx.core.entities.Region;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#Named
#ViewScoped
public class GeoLists implements Serializable {
#Inject
EntityManager entityManager;
#Inject
ISNetApp sNetApp;
private List<Country> countryList;
public List<Country> getCountryList() {
if (countryList == null) {
String query = "select c from Country c order by c.ordering, c.name";
countryList = (List<Country>) entityManager.createQuery(query).getResultList();
}
return countryList;
}
public void setCountryList(List<Country> countryList) {
this.countryList = countryList;
}
private List<Country> deliveryCountryList;
public List<Country> getDeliveryCountryList() {
if (deliveryCountryList == null) {
String query = "select c from Country c where c.groups LIKE '%D,%' order by c.ordering, c.name";
deliveryCountryList = (List<Country>) entityManager.createQuery(query).getResultList();
}
return deliveryCountryList;
}
public void setDeliveryCountryList(List<Country> deliveryCountryList) {
this.deliveryCountryList = deliveryCountryList;
}
public Country getCountryByIsoCode2(String isoCode2) {
String query = "select c from Country c where c.isoCode2=:ic";
try {
return (Country) entityManager.createQuery(query).setParameter("ic", isoCode2).getSingleResult();
} catch (NoResultException e) {
return null;
}
}
private List<Region> regionForCountry;
private int countryIdCache;
private List<Region> regions;
public List<Region> getRegions(){
return this.regions;
}
public void setRegions(List<Region> regions){
this.regions = regions;
}
public List<Region> getRegionForCountryById(Long countryId) {
Country country = entityManager.find(Country.class, countryId.intValue());
return getRegionForCountry(country);
}
public List<Region> getRegionForCountry(Country country) {
try{
System.out.println("bbbbbbbbbbbbbbbbbbbbbbb" + country.toString());
//if (regionForCountry == null || countryIdCache != country.getId()) {
regionForCountry = entityManager.createQuery("select r From Region r Where r.country.id = :countryId order by r.description ")
.setParameter("countryId", 1)//country.getId())
.getResultList();
// countryIdCache = country.getId();
//}
// System.out.println("aaaaaaaaaaa" + regionForCountry.toString());
} catch(Exception e){System.out.println("cccccccccc"); return new ArrayList<Region>(); }
return regionForCountry;
}
public void setRegionForCountry(List<Region> regionForCountry) {
this.regionForCountry = regionForCountry;
}
private Country mainCountry;
private Country country;
public void setCountry(Country country) {
this.country=country;
}
public Country getCountry(){
return this.country;
}
public Country getMainCountry() {
if (mainCountry == null) {
mainCountry = entityManager.find(Country.class, sNetApp.getMainCountryId());
}
return mainCountry;
}
public void setMainCountry(Country mainCountry) {
this.mainCountry = mainCountry;
}
private List<Country> specificGroupCountryList;
private String groupCache;
public List<Country> getSpecificGroupCountryList(String group) {
if (specificGroupCountryList == null || groupCache == null || groupCache.compareTo(group) != 0) {
String query = "from Country where groups LIKE '%" + group + ",%' order by ordering, name";
specificGroupCountryList = (List<Country>) entityManager.createQuery(query).getResultList();
}
return specificGroupCountryList;
}
public void setSpecificGroupCountryList(List<Country> specificGroupCountryList) {
this.specificGroupCountryList = specificGroupCountryList;
}
}
mbcActor is a param defined as:
<ui:param name="mbcActor" value="#{registrationHelper.newActor}"/>
AbstractActor:
#MappedSuperclass
public class AbstractActor extends AbstractGenericElement implements java.io.Serializable, IGenericElement, EmailContact {
private static Logger log = LoggerFactory.getLogger(AbstractActor.class);
public static enum Gender {
Male,
Female
}
/**
* Transient
*/
private boolean selected;
private Integer id;
private Long version;
private byte type;
private String language;
private byte status;
private byte publicStatus;
private String permalink;
private Boolean customPermalink;
private String displayName;
private String forename;
private String surname;
private Gender gender;
private Date birthday;
private String mobile;
private Byte subType;
private String stringValue1;
private String stringValue2;
private String stringValue3;
#Transient
#XmlTransient
private Integer age;
private String profileMessage;
private String statusMessage;
private String email;
private String username;
private String passwordHash;
private int passwordHashIterations;
private String salt;
private String timezone;
private String activationCode;
private Boolean activationEmailSent;
private Integer completitionPercentage;
private Integer ordering;
// Stats
private ActorStats stats;
// Extensions
private DataActorGeo geoData;
private DataActorExtended dataActorExtended;
private Boolean acceptNewsletter;
private Boolean emailAlertsEnabled;
private Set<ActorTag> actorTags = new HashSet<ActorTag>(0);
private List<Role> roles = new ArrayList<Role>(0);
private Actor newDataToBeModerated;
private Date expireDate;
private Integer points;
private BigDecimal wallet;
private Byte emailAlertsType;
private Byte emailOffersType;
private String emailHash;
// Data blob
private byte[] data;
private Set<ActorInCategory> actorInCategories = new HashSet<ActorInCategory>(
0);
private List<ActorAttribute> actorAttributes = new ArrayList<ActorAttribute>(0);
public AbstractActor() {
this.version = 1l;
this.activationEmailSent = false;
this.acceptNewsletter = true;
this.emailAlertsEnabled = true;
this.completitionPercentage = 0;
this.customPermalink = false;
this.wallet = new BigDecimal(0);
this.points = 0;
this.emailAlertsType = ActorConstants.RECURRING_EMAIL_TYPE_NONE;
this.emailOffersType = ActorConstants.RECURRING_EMAIL_TYPE_NONE;
}
public AbstractActor(byte type, byte status) {
this.version = 1l;
this.type = type;
this.status = status;
this.publicStatus = ActorConstants.PUBLIC_STATUS_OFFLINE;
this.activationEmailSent = false;
this.acceptNewsletter = true;
this.emailAlertsEnabled = true;
this.completitionPercentage = 0;
this.customPermalink = false;
this.wallet = new BigDecimal(0);
this.points = 0;
this.emailAlertsType = ActorConstants.RECURRING_EMAIL_TYPE_NONE;
this.emailOffersType = ActorConstants.RECURRING_EMAIL_TYPE_NONE;
}
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "geoData", nullable = true)
#org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public DataActorGeo getGeoData() {
return this.geoData;
}
public void setGeoData(DataActorGeo geoData) {
this.geoData = geoData;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "actor")
public Set<ActorInCategory> getActorInCategories() {
return this.actorInCategories;
}
public void setActorInCategories(Set<ActorInCategory> actorInCategories) {
this.actorInCategories = actorInCategories;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "actor")
public List<ActorAttribute> getActorAttributes() {
return this.actorAttributes;
}
public void setActorAttributes(List<ActorAttribute> actorAttributes) {
this.actorAttributes = actorAttributes;
}
}
Your <p:ajax> tag uses the render attribute, which isn't predefined. The attribute you want is update.
supposing that registrationHelper.newActor is an instance of of a Managed Bean, I think it's probably not initialized. Why don't you make sure it is, by creating it on RegistrationHelper's PostConstruct, or even get it through a method like
public AbstractActor createNewActor() {
newActor = new AbstractActor();
return newActor;
}
<ui:param name="mbcActor" value="#{registrationHelper.createNewActor}"/>
Perhaps someone here can give me a tip where the error could be situated (JSF 2.2, Glassfish 4.0):
I have two entities with a manytomany relation (see example)
When I deploy my project in glassfish all tables (also the linking table) are generated correctly (create-tables enabled in persistence.xml): TAGUSERWISH, TAGUSERWISH_WISH (linking table), WISH
When I execute a persist (see example) entity "wish" and "tagUserWish" is persisted correctly, but nothing is written into the linking table when I look directly into the mysql table. But when I read "wish" out with JPA, the List<TagUserWish> is filled
As soon as a new session starts (redeploy) List<TagUserWish> is also empty when read out with JPA
Owner entity:
#Entity
public class Wish implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String subject;
private String abstractT;
#OneToOne
private User user;
#ManyToMany(mappedBy = "wishes", cascade = {CascadeType.ALL} )
private List<TagUserWish> tags = new LinkedList<>();
public void addTag(TagUserWish tag){
tags.add(tag);
}
public void setTags(List<TagUserWish> tags) {
this.tags = tags;
}
public void removeTag(TagUserWish tag){
tags.remove(tag);
}
public List<TagUserWish> getTags(){
return tags;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getAbstractT() {
return abstractT;
}
public void setAbstractT(String abstractT) {
this.abstractT = abstractT;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Wish)) {
return false;
}
Wish other = (Wish) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "eu.citato.main.model.Wish[ id=" + id + " ]";
}
}
Entity 2:
#Entity
public class TagUserWish implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public TagUserWish() {
}
public TagUserWish(String name) {
this.name = name;
}
#ManyToMany
private List<Wish> wishes = new LinkedList<>();
public void addWish(Wish wish){
wishes.add(wish);
}
public void setWishes(List<Wish> wishes) {
this.wishes = wishes;
}
public void removeWish(Wish tag){
wishes.remove(tag);
}
public List<Wish> getWishes(){
return wishes;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 TagUserWish)) {
return false;
}
TagUserWish other = (TagUserWish) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "eu.citato.main.model.Tag[ id=" + id + ", name="+name+" ]";
}
}
How I persist it:
#javax.inject.Named
#SessionScoped
public class WishPM implements Serializable {
#EJB
private WishService wls;
public void commitEditWish(){
List<TagUserWish> selTags = new ArrayList<>();
selTags.add(new TagUserWish("Tag1"));
selTags.add(new TagUserWish("Tag2"));
currentWish = new Wish();
currentWish.setSubject("wishSubject");
currentWish.setAbstractT("wishAbstract");
currentWish.setTags(selTags);
wls.createWish(currentWish);
}
}
And the wish Service:
#Stateless
public class WishService implements Serializable{
#PersistenceContext(unitName = "WishlistPU")
private EntityManager em;
public void createWish(Wish entity){
em.persist(entity);
}
}
Relationships are persisted based to the owner side of relationship. Owner of the bidirectional relationship is one that is value of mappedBy in inverse side. In following case owner of the relationship is wishes field in TagUserWish entity
#ManyToMany(mappedBy = "wishes", cascade = {CascadeType.ALL} )
private List<TagUserWish> tags = new LinkedList<>();
Because instance of TagUserWish do have empty wishes collection, relationship is not persisted. Problem can be solved by adding related Wish to the instance of TagUserWish, for example as follows:
...
TagUserWish tuw1 = new TagUserWish("Tag1")
TagUserWish tuw2 = new TagUserWish("Tag2")
selTags.add(tuw1);
selTags.add(tuw2);
currentWish = new Wish();
tuw1.addWish(currentWish); //setting to owner side of relationship
tuw2.addWish(currentWish); //setting to owner side of relationship
...
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.
i have an association table called MenuPrevilege between 2 tables called Menu and Previlege.
In order to get all menus of a specific previlege i created a named query in the Menu entity:
#Entity
#NamedQueries( {
#NamedQuery(name = "getAllMenus", query = "select m from Menu m"),
#NamedQuery(name = "getMenusByPrevilegeId", query = "select m from Menu m
JOIN m.menuPrevilege mp where mp.previlege_id = :p")})
public class Menu implements Serializable {
private String url;
private String description;
private List<MenuPrevilege> menuPrevilges;
private static final long serialVersionUID = 1L;
public Menu() {
super();
}
#Id
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setMenuPrevilges(List<MenuPrevilege> menuPrevilges) {
if (menuPrevilges == null)
menuPrevilges = new ArrayList<MenuPrevilege>();
this.menuPrevilges = menuPrevilges;
}
#OneToMany(mappedBy = "menu", cascade = CascadeType.REMOVE)
public List<MenuPrevilege> getMenuPrevilges() {
if (menuPrevilges == null)
menuPrevilges = new ArrayList<MenuPrevilege>();
return menuPrevilges;
}
public Menu(String url, String description) {
super();
this.url = url;
this.description = description;
}
}
i'm having this exception org.hibernate.QueryException: could not resolve property:menuPrevilege , and i don't know how to deal with it. this is the MenuPrevilege entity:
#Entity
#Table(name = "Menu_Previlege")
public class MenuPrevilege implements Serializable {
private IdMenuPrevilege idmenuPrevilege = new IdMenuPrevilege();
private Date activationDate;
private Date deactivationDate;
private Menu menu;
private Previlege previlege;
private static final long serialVersionUID = 1L;
public MenuPrevilege() {
super();
}
#EmbeddedId
public IdMenuPrevilege getIdmenuPrevilege() {
return this.idmenuPrevilege;
}
public void setIdmenuPrevilege(IdMenuPrevilege idmenuPrevilege) {
this.idmenuPrevilege = idmenuPrevilege;
}
#Temporal(TemporalType.DATE)
public Date getActivationDate() {
return this.activationDate;
}
public void setActivationDate(Date activationDate) {
this.activationDate = activationDate;
}
#Temporal(TemporalType.DATE)
public Date getDeactivationDate() {
return this.deactivationDate;
}
public void setDeactivationDate(Date deactivationDate) {
this.deactivationDate = deactivationDate;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
#ManyToOne
#JoinColumn(name = "menu_id", insertable = false, updatable = false)
public Menu getMenu() {
return menu;
}
public void setPrevilege(Previlege previlege) {
this.previlege = previlege;
}
#ManyToOne
#JoinColumn(name = "previlege_id", insertable = false, updatable = false)
public Previlege getPrevilege() {
return previlege;
}
public MenuPrevilege(Menu menu, Previlege previlege) {
super();
getIdmenuPrevilege().setIdMenu(menu.getUrl());
getIdmenuPrevilege().setIdPrevilege(previlege.getPrevilegeId());
this.setMenu(menu);
this.setPrevilege(previlege);
menu.getMenuPrevilges().add(this);
previlege.getPrevilegeMenus().add(this);
}
}
I made name refactoring to my code edit my query and everything seems to be working. Here are the changes :
in the named query:
#NamedQuery(name = "getMenusByPrevilegeId", query = "select m from Menu m JOIN
m.previleges p where p.previlege.previlegeId = :p")})
the entity attribute
private List<MenuPrevilege> previleges;
// getters and setters as well
in the constructor of the MenuPrevilege entity
public MenuPrevilege(Menu menu, Previlege previlege) {
super();
getIdmenuPrevilege().setIdMenu(menu.getUrl());
getIdmenuPrevilege().setIdPrevilege(previlege.getPrevilegeId());
this.setMenu(menu);
this.setPrevilege(previlege);
menu.getPrevileges().add(this);
previlege.getMenus().add(this);
}
as u can notice it was a syntax error in my query that caused the exception.