I have 3 tables. Hospitals and doctors. The 3rd table is a junction table of both that contains id,ids of 2 other tables as foreign keys and few other columns. When trying to put record to a junction table I got an error that one of foreign keys have to be set with insertable=false. However when I set it like this then I get that the value can't be null (since my database requires that field).I'm stuck and can't go any further with those 2 errors.
If I manage to avoid those 2 errors then I get an erorr that there is an unknown column in the field list.
Doctors entity:
#Entity
#Table(name = "doctors")
public class Doctors implements Serializable {
private Integer id;
private String name;
private String surname;
private String title;
private String licenseNumber;
private String phone;
private String email;
private String nationality;
private String speciality;
private LocalDate dateOfBirth;
private Boolean isATeacher;
private List<HospitalDoctors> hospitalDoctors = new LinkedList<>();
//consturctors
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "Idd", nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
//setters and getters for rest of the fields with #column annotations on getters
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.doctor", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
public List<HospitalDoctors> getHospitalDoctors() {
return hospitalDoctors;
}
public void setHospitalDoctors(List<HospitalDoctors> hospitalDoctors) {
this.hospitalDoctors = hospitalDoctors;
}
Hospitals entity:
#Entity
#Table(name = "hospitals")
public class Hospitals implements Serializable {
private Integer id;
private String name;
private String country;
private String town;
private String street;
private String postalCode;
private String phoneNumber;
private String faxNumber;
private Integer numberOfAmbulances;
private Boolean helicopterAccess;
private Boolean teachingHospital;
private List<HospitalDoctors> hospitalDoctors = new LinkedList<>();
//constructors
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "Idh", nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
//getters setters with #column annotations over getters
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.hospital", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
public List<HospitalDoctors> getHospitalDoctors() {
return this.hospitalDoctors;
}
public void setHospitalDoctors(List<HospitalDoctors> hospitalDoctors) {
this.hospitalDoctors = hospitalDoctors;
}
Junction table entity:
#Entity
#Table(name = "hospitaldoctors")
#AssociationOverrides({
#AssociationOverride(name = "pk.hospital",
joinColumns = #JoinColumn(name = "Idh")),
#AssociationOverride(name = "pk.doctor",
joinColumns = #JoinColumn(name = "Idd"))
})
public class HospitalDoctors implements Serializable {
private Integer id;
private Integer idH;
private Integer idD;
private HospitalDoctorsId pk = new HospitalDoctorsId();
private LocalDate contractStartDate;
private LocalDate contractEndDate;
private String position;
private Boolean supervisor;
private Boolean partTime;
//constructors
#Column(name ="Idhos")
public Integer getIdH() {
return this.idH;
}
public void setIdH(Integer idH) {
this.idH = idH;
}
#Column(name ="Iddoc")
public Integer getIdD() {
return this.idD;
}
public void setIdD(Integer idD) {
this.idD = idD;
}
#EmbeddedId
public HospitalDoctorsId getPk() {
return pk;
}
public void setPk(HospitalDoctorsId pk) {
this.pk = pk;
}
#Transient
public Hospitals getHospital(){
return getPk().getHospital();
}
public void setHospital(Hospitals hospital){
getPk().setHospital(hospital);
}
#Transient
public Doctors getDoctor(){
return getPk().getDoctor();
}
public void setDoctor(Doctors doctor){
getPk().setDoctor(doctor);
}
//rest of the setters getters with #Column
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HospitalDoctors that = (HospitalDoctors) o;
if(getPk() != null?!getPk().equals(that.getPk()) : that.getPk() != null) return false;
return true;
}
#Override
public int hashCode() {
return (getPk() != null? getPk().hashCode() : 0);
}
Junction table Id:
#Embeddable
public class HospitalDoctorsId implements Serializable {
private Hospitals hospital;
private Doctors doctor;
#ManyToOne
public Hospitals getHospital() {
return hospital;
}
public void setHospital(Hospitals hospital) {
this.hospital = hospital;
}
#ManyToOne
public Doctors getDoctor() {
return doctor;
}
public void setDoctor(Doctors doctor) {
this.doctor = doctor;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HospitalDoctorsId that = (HospitalDoctorsId) o;
if(hospital != null?!hospital.equals(that.hospital) : that.hospital != null) return false;
if(doctor != null?!doctor.equals(that.doctor) : that.doctor != null) return false;
return true;
}
#Override
public int hashCode() {
int result;
result = (hospital != null? hospital.hashCode() : 0);
result = 31* result + (doctor != null? doctor.hashCode() : 0);
return result;
}
}
I expected to be able to add records to junction table in data base in form fields I have foreign keys for hospital and doctors id to put in as well as other fields. Unfortunately I get either error that say to put foreign keys columns idD and idH as insertable, updatable false which leads to null value being passed which gives another error. When I solve those errors I get the error:
java.sql.SQLSyntaxErrorException: Unknown column 'hospitaldo0_.Idd' in 'field list'when trying to display records nad unknown column Idd when trying to add record (displaying works when Im getting insertable error or null value error. adding never works)
If I remember correctly, you need to have a single #ManyToMany relation rather than two #OneToMany relations.
In our software, we had a requirement that display name of one UI will be configurable according to user. So one user want to display another column from one table and another user want to display another column from same table. I think I can do this using SqlResultSetMappings and automatic name query. display_name column is not in database . I think that I can map column name(according to user selection) to displayName. The problem, Jpa 2.0 does not have type in Columnresult annotation. So display name returns Character. This is my entity definition. In this eaxample user want to display short_name in the UIs. But another user can want to show name in the UIs.
#SqlResultSetMappings({
#SqlResultSetMapping(name = "findAllByTypeList", entities = #EntityResult(entityClass = Element.class, fields = {
#FieldResult(name = "id", column = "ID"), #FieldResult(name = "variant", column = "VARIANT_ID"),
#FieldResult(name = "elementType", column = "ELEMENT_TYPE_ID"),
#FieldResult(name = "name", column = "NAME"),
#FieldResult(name = "shortName", column = "SHORT_NAME"),
#FieldResult(name = "displayName", column = "display_name")
}), columns = {
#ColumnResult(name = "display_name")
})
})
public class Element implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2892631423222044026L;
public Element () {
super();
}
#Id
#Column(name = "ID")
private long id;
#ManyToOne
#JoinColumn(name = "VARIANT_ID")
private Variant variant;
#Column(name = "ELEMENT_TYPE_ID")
private int elementType;
#Column(name = "NAME")
private String name;
#Column(name = "SHORT_NAME")
private String shortName;
#Transient
private String displayName;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Variant getVariant() {
return variant;
}
public void setVariant(Variant variant) {
this.variant = variant;
}
public ElementTypeConstants getElementType() {
return ElementTypeConstants .getInstance(elementType);
}
public void setElementType(NetworkElementTypeConstants elementType) {
this.elementType = elementType.getId();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Element)) {
return false;
}
if (obj == this) {
return true;
}
return ((Element) obj).getName().equals(this.getName());
}
public String toString() {
StringBuffer buf = new StringBuffer("NE ID:");
buf.append(getId());
buf.append(", Name:");
buf.append(getName());
buf.append(", ShortName:");
buf.append(getShortName());
return buf.toString();
}
#Override
public int hashCode() {
return Long.valueOf(id).intValue();
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
This is my native query
/** adding table name */
sqlQuery = "select a.id, a.variant_id, a.ELEMENT_TYPE_ID, a.name, a.short_name, a.short_name as display_name from " + conf_element a;
Query query = em.createNativeQuery(sqlQuery
+ " where a.variant_id=:variantId and a.element_type_id in (:elementTypeIdList) order by a.name",
"findAllByTypeList");
query.setParameter("variantId", variantId);
query.setParameter("elementTypeIdList", elementTypeList);
return query.getResultList();
}
PS.: In the beginning, I think that I can implement without using ColumnResult.Following line can do the job.
#FieldResult(name = "displayName", column = "display_name")
There are questions similar but not quite. In those cases (and in the JPAContainer examples) the Entity part of the ManyToOne relationship has a single key. In my case it is an embedded id.
My code is based on the Address Book example.
Here are the three entities:
#Entity
#Table(name = "tutorial")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Tutorial.findAll", query = "SELECT t FROM Tutorial t"),
#NamedQuery(name = "Tutorial.findById", query = "SELECT t FROM Tutorial t WHERE t.tutorialPK.id = :id"),
#NamedQuery(name = "Tutorial.findByTutorialTypeId", query = "SELECT t FROM Tutorial t WHERE t.tutorialPK.tutorialTypeId = :tutorialTypeId"),
#NamedQuery(name = "Tutorial.findByMessage", query = "SELECT t FROM Tutorial t WHERE t.message = :message")})
public class Tutorial implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected TutorialPK tutorialPK;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 245)
#Column(name = "message")
private String message;
#JoinColumn(name = "tutorial_type_id", referencedColumnName = "id", insertable = false, updatable = false)
#ManyToOne(optional = false)
private TutorialType tutorialType;
public Tutorial() {
}
public Tutorial(TutorialPK tutorialPK) {
this.tutorialPK = tutorialPK;
}
public Tutorial(TutorialPK tutorialPK, String message) {
this.tutorialPK = tutorialPK;
this.message = message;
}
public Tutorial(int id, int tutorialTypeId) {
this.tutorialPK = new TutorialPK(id, tutorialTypeId);
}
public TutorialPK getTutorialPK() {
return tutorialPK;
}
public void setTutorialPK(TutorialPK tutorialPK) {
this.tutorialPK = tutorialPK;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public TutorialType getTutorialType() {
return tutorialType;
}
public void setTutorialType(TutorialType tutorialType) {
this.tutorialType = tutorialType;
}
#Override
public int hashCode() {
int hash = 0;
hash += (tutorialPK != null ? tutorialPK.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 Tutorial)) {
return false;
}
Tutorial other = (Tutorial) object;
if ((this.tutorialPK == null && other.tutorialPK != null) || (this.tutorialPK != null && !this.tutorialPK.equals(other.tutorialPK))) {
return false;
}
return true;
}
#Override
public String toString() {
return "games.jwrestling.server.game.db.persistence.Tutorial[ tutorialPK=" + tutorialPK + " ]";
}
}
And the EmbeddedId class:
#Embeddable
public class TutorialPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "id")
private int id;
#Basic(optional = false)
#NotNull
#Column(name = "tutorial_type_id")
private int tutorialTypeId;
public TutorialPK() {
}
public TutorialPK(int id, int tutorialTypeId) {
this.id = id;
this.tutorialTypeId = tutorialTypeId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTutorialTypeId() {
return tutorialTypeId;
}
public void setTutorialTypeId(int tutorialTypeId) {
this.tutorialTypeId = tutorialTypeId;
}
#Override
public int hashCode() {
int hash = 0;
hash += (int) id;
hash += (int) tutorialTypeId;
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 TutorialPK)) {
return false;
}
TutorialPK other = (TutorialPK) object;
if (this.id != other.id) {
return false;
}
if (this.tutorialTypeId != other.tutorialTypeId) {
return false;
}
return true;
}
#Override
public String toString() {
return "games.jwrestling.server.game.db.persistence.TutorialPK[ id=" + id + ", tutorialTypeId=" + tutorialTypeId + " ]";
}
}
And another one:
#Entity
#Table(name = "tutorial_type")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "TutorialType.findAll", query = "SELECT t FROM TutorialType t"),
#NamedQuery(name = "TutorialType.findById", query = "SELECT t FROM TutorialType t WHERE t.id = :id"),
#NamedQuery(name = "TutorialType.findByType", query = "SELECT t FROM TutorialType t WHERE t.type = :type"),
#NamedQuery(name = "TutorialType.findByDescription", query = "SELECT t FROM TutorialType t WHERE t.description = :description")})
public class TutorialType implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#GeneratedValue(strategy = GenerationType.TABLE, generator = "TutorialTypeGen")
#TableGenerator(name = "TutorialTypeGen", table = "jwrestling_id",
pkColumnName = "tablename",
valueColumnName = "last_id",
pkColumnValue = "tutorial_type",
allocationSize = 1,
initialValue = 1)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "type")
private String type;
#Size(max = 245)
#Column(name = "description")
private String description;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "tutorialType")
private List<Tutorial> tutorialList;
public TutorialType() {
}
public TutorialType(Integer id) {
this.id = id;
}
public TutorialType(Integer id, String type) {
this.id = id;
this.type = type;
}
public TutorialType(String type, String desc) {
this.type = type;
this.description = desc;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#XmlTransient
public List<Tutorial> getTutorialList() {
return tutorialList;
}
public void setTutorialList(List<Tutorial> tutorialList) {
this.tutorialList = tutorialList;
}
#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 TutorialType)) {
return false;
}
TutorialType other = (TutorialType) 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 "games.jwrestling.server.game.db.persistence.TutorialType[ id=" + id + " ]";
}
}
I got the form set up and it works fine when I edit the items, but creating I get errors because the TutorialPK is null:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'tutorial_type_id' cannot be null
Here are the related Vaadin code:
public final class TutorialEditor extends Window implements Button.ClickListener,
FormFieldFactory {
private final Item tutorialItem;
private final Form editorForm;
private final Button saveButton;
private final Button cancelButton;
public TutorialEditor(Item tutorialItem) {
this.tutorialItem = tutorialItem;
editorForm = new Form();
editorForm.setFormFieldFactory(this);
editorForm.setBuffered(true);
editorForm.setImmediate(true);
editorForm.setItemDataSource(tutorialItem, Arrays.asList("message",
"tutorialType"));
saveButton = new Button("Save", this);
cancelButton = new Button("Cancel", this);
editorForm.getFooter().addComponent(saveButton);
editorForm.getFooter().addComponent(cancelButton);
setSizeUndefined();
setContent(editorForm);
setCaption("New Tutorial");
}
#Override
public void buttonClick(Button.ClickEvent event) {
if (event.getButton() == saveButton) {
editorForm.commit();
fireEvent(new EditorSavedEvent(this, tutorialItem));
} else if (event.getButton() == cancelButton) {
editorForm.discard();
}
close();
}
#Override
public Field<?> createField(Item item, Object propertyId, Component uiContext) {
Field field = DefaultFieldFactory.get().createField(item, propertyId,
uiContext);
if ("tutorialType".equals(propertyId)) {
field = new TutorialTypeSelector();
} else if (field instanceof TextField) {
((TextField) field).setNullRepresentation("");
}
field.addValidator(new BeanValidator(Tutorial.class, propertyId
.toString()));
return field;
}
public void addListener(EditorSavedListener listener) {
try {
Method method = EditorSavedListener.class.getDeclaredMethod(
"editorSaved", new Class[]{EditorSavedEvent.class});
addListener(EditorSavedEvent.class, listener, method);
} catch (final java.lang.NoSuchMethodException e) {
// This should never happen
throw new java.lang.RuntimeException(
"Internal error, editor saved method not found");
}
}
public void removeListener(EditorSavedListener listener) {
removeListener(EditorSavedEvent.class, listener);
}
public static class EditorSavedEvent extends Component.Event {
private final Item savedItem;
public EditorSavedEvent(Component source, Item savedItem) {
super(source);
this.savedItem = savedItem;
}
public Item getSavedItem() {
return savedItem;
}
}
public interface EditorSavedListener extends Serializable {
public void editorSaved(EditorSavedEvent event);
}
And another one:
class TutorialTypeSelector extends CustomField<TutorialType> {
private final JPAContainer<TutorialType> container;
private final ComboBox type = new ComboBox();
public TutorialTypeSelector() {
container = JPAContainerFactory.make(TutorialType.class,
"JWPUJNDI");
setCaption("Type");
type.setContainerDataSource(container);
type.setItemCaptionPropertyId("type");
type.addListener(new Property.ValueChangeListener() {
#Override
public void valueChange(
com.vaadin.data.Property.ValueChangeEvent event) {
/*
* Modify the actual value of the custom field.
*/
if (type.getValue() == null) {
setValue(null, false);
} else {
TutorialType entity = container
.getItem(type.getValue()).getEntity();
setValue(entity, false);
}
}
});
}
#Override
protected Component initContent() {
CssLayout cssLayout = new CssLayout();
cssLayout.addComponent(type);
return cssLayout;
}
#Override
public void setPropertyDataSource(Property newDataSource) {
super.setPropertyDataSource(newDataSource);
setTutorialType((TutorialType) newDataSource.getValue());
}
#Override
public void setValue(TutorialType newValue) throws ReadOnlyException,
Converter.ConversionException {
super.setValue(newValue);
setTutorialType(newValue);
}
private void setTutorialType(TutorialType type) {
this.type.setValue(type != null ? type.getId() : null);
}
#Override
public Class<? extends TutorialType> getType() {
return TutorialType.class;
}
}
Any idea on how to populate this field?
Update:
Error after using #MapsId
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [tutorial.tutorial_type_id].
Descriptor: RelationalDescriptor(games.jwrestling.server.game.db.persistence.Tutorial --> [DatabaseTable(tutorial)])
Two ways. If using JPA 1.0, you will need to pull the value from the referenced tutorialType and manually add it to the tutorial.tutorialPK.tutorialTypeId. You didn't include the tutorialType entity, but if it's ID value is generated, you may need to persist it and flush before the value is assigned.
If using JPA 2.0, you can specify the #MapsId annotation in your entity, allowing JPA to set the tuturial.tutorialPK.tutorialTypeId value from the tutorial.tutorialType reference for you:
public class Tutorial implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
protected TutorialPK tutorialPK;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 245)
#Column(name = "message")
private String message;
#MapsId("tutorialTypeId")
#ManyToOne(optional = false)
private TutorialType tutorialType;
You will not be able to change the TutorialType associated to a tutorial once it is created though - the only option is to delete the existing one and create a new one with the new values.
I have an issue with creating a query with hibernate template. I've take a look at many tutorial and i create my query that look like this
List fids = getHibernateTemplate().execute(new HibernateCallback<List>() {
#Override
public List doInHibernate(Session session) throws HibernateException {
Query query = session.createQuery(
"SELECT DISTINCT m.fournisseurs_id FROM Medicamentfournisseur as m, Composantcommandeclient as c WHERE c.medicamentsFournisseurs_id= m.id AND c.commandeclients_id = :id"
);
query.setParameter(":id", id);
return query.list();
}
});
I try query in SQL console and it works but in my apps i got this error :
error :could not resolve property: fournisseurs_id of: com.project.caritas.model.Medicamentfournisseur [SELECT DISTINCT m.fournisseurs_id FROM com.project.caritas.model.Medicamentfournisseur as m, com.project.caritas.model.Composantcommandeclient as c WHERE c.medicamentsFournisseurs_id= m.id AND c.commandeclients_id = :id]; nested exception is org.hibernate.QueryException: could not resolve property: fournisseurs_id of: com.project.caritas.model.Medicamentfournisseur [SELECT DISTINCT m.fournisseurs_id FROM com.project.caritas.model.Medicamentfournisseur as m, com.project.caritas.model.Composantcommandeclient as c WHERE c.medicamentsFournisseurs_id= m.id AND c.commandeclients_id = :id]
there is my POJO
#Entity
#Table(name = "medicamentfournisseur", catalog = "salama")
public class Medicamentfournisseur implements java.io.Serializable {
private Integer id;
private Fournisseur fournisseur;
private double prix;
private String designation;
private String laboratoire;
private String datePeremption;
private String tva;
private Integer disponible;
private Set composantcommandeclients = new HashSet(0);
public Medicamentfournisseur() {
}
public Medicamentfournisseur(Fournisseur fournisseur, double prix, String datePeremption) {
this.fournisseur = fournisseur;
this.prix = prix;
this.datePeremption = datePeremption;
}
public Medicamentfournisseur(Fournisseur fournisseur, double prix, String designation, String laboratoire, String datePeremption, String tva, Integer disponible, Set composantcommandeclients) {
this.fournisseur = fournisseur;
this.prix = prix;
this.designation = designation;
this.laboratoire = laboratoire;
this.datePeremption = datePeremption;
this.tva = tva;
this.disponible = disponible;
this.composantcommandeclients = composantcommandeclients;
}
#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 = "fournisseurs_id", nullable = false)
public Fournisseur getFournisseur() {
return this.fournisseur;
}
public void setFournisseur(Fournisseur fournisseur) {
this.fournisseur = fournisseur;
}
#Column(name = "prix", nullable = false, precision = 22, scale = 0)
public double getPrix() {
return this.prix;
}
public void setPrix(double prix) {
this.prix = prix;
}
#Column(name = "designation", length = 200)
public String getDesignation() {
return this.designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
#Column(name = "laboratoire", length = 200)
public String getLaboratoire() {
return this.laboratoire;
}
public void setLaboratoire(String laboratoire) {
this.laboratoire = laboratoire;
}
#Column(name = "datePeremption", nullable = false, length = 200)
public String getDatePeremption() {
return this.datePeremption;
}
public void setDatePeremption(String datePeremption) {
this.datePeremption = datePeremption;
}
#Column(name = "tva", length = 50)
public String getTva() {
return this.tva;
}
public void setTva(String tva) {
this.tva = tva;
}
#Column(name = "disponible")
public Integer getDisponible() {
return this.disponible;
}
public void setDisponible(Integer disponible) {
this.disponible = disponible;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "medicamentfournisseur")
#JsonIgnore
public Set getComposantcommandeclients() {
return this.composantcommandeclients;
}
public void setComposantcommandeclients(Set composantcommandeclients) {
this.composantcommandeclients = composantcommandeclients;
}
}
If someone can explain me how to solve this.
PS: Sorry for my bad english
you should use:
SELECT DISTINCT m.fournisseurs FROM Medicamentfournisseur as m ...
Because this is not a sql actually, it is a HQL of hibernate like sql. You should use the member name in java but not table column name.
Been messing around with Hibernate and PostgreSQL trying to get it to work as expected.
But for some reason when I try to persist an object with a #OneToMany relationship with more than one item in the set all but the first item seem to be ignored. I've tried this via local and remote interfaces but get the same results each time. No exceptions are thrown, it looks like hibernate just stops persisting after the first unit has been persisted.
Any help much appreciated this one has been eluding me for days now.
I'm using Hibernate 3.5 and PostgreSQL 8.4.4 with Glassfish v3. All the annotations in the source are from the package javax.persistence - had to remove imports because of the character limit.
The FacadeManager is simply a utility to take the hassle out of jndi lookups, it simplifies accessing remote facades.
Here is the test method
#Test
public void testOneToManyCascade() throws Exception {
/*
* Set up entities requred to perform the test
*/
UnitFacadeRemote unitfr = FacadeManager
.getFacade(UnitFacadeRemote.class);
UserFacadeRemote userfr = FacadeManager
.getFacade(UserFacadeRemote.class);
User user = new User("P", "P", "000000", true, new Date(), "ypy#ypy",
"wordof mout", "slacker", "password");
Address address = new Address("yo", "go", "YOKO", "4123");
address.setCountry(FacadeManager.getFacade(CountryFacadeRemote.class)
.find(2));
user.setAddress(address);
Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService",
"MyNation");
Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService",
"TheirNation");
Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService",
"TheirNation");
// Check no game exists
assertThat(FacadeManager.getFacade(GameFacadeRemote.class).findAll()
.size(), is(0));
Game game = new Game("blabla", 3333, "A game!", true);
// Create game and return reference to persisted game instance
game = FacadeManager.getFacade(GameFacadeRemote.class).registerGame(
game);
unit1.setGame(game);
unit2.setGame(game);
unit3.setGame(game);
// Find a virtue
Virtue v = FacadeManager.getFacade(VirtueFacadeRemote.class).find(1);
unit1.setVirtue(v);
unit2.setVirtue(v);
unit3.setVirtue(v);
// check that none of the above exist already
assertThat(userfr.findAll().size(), is(0));
assertThat(unitfr.findAll().size(), is(0));
/*
* Try persisting the by cascading from the user
*/
Set<Unit> unitSet = new HashSet<Unit>();
unitSet.add(unit2);
unitSet.add(unit1);
unitSet.add(unit3);
user.setUnitSet(unitSet);
unit1.setUser(user);
unit2.setUser(user);
unit3.setUser(user);
// Persist
userfr.create(user);
/*
* The result of the preceding persist is that the game, user, address
* and one unit are persisted, in this case unit2 but it seems whichever
* unit is first added to unitSet is the one that is persisted.
*/
}
Here follow the various entity classes
package com.game.database.entity;
#Entity
#Table(name = "address")
#NamedQueries({
#NamedQuery(name = "Address.findAll", query = "SELECT a FROM Address a"),
#NamedQuery(name = "Address.findById", query = "SELECT a FROM Address a WHERE a.id = :id"),
#NamedQuery(name = "Address.findByLine1", query = "SELECT a FROM Address a WHERE a.line1 = :line1"),
#NamedQuery(name = "Address.findByLine2", query = "SELECT a FROM Address a WHERE a.line2 = :line2"),
#NamedQuery(name = "Address.findByCity", query = "SELECT a FROM Address a WHERE a.city = :city"),
#NamedQuery(name = "Address.findByAreaCode", query = "SELECT a FROM Address a WHERE a.areaCode = :areaCode") })
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "address_id_seq", sequenceName = "address_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "address_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "line1")
private String line1;
#Basic(optional = false)
#Column(name = "line2")
private String line2;
#Basic(optional = false)
#Column(name = "city")
private String city;
#Basic(optional = false)
#Column(name = "areaCode")
private String areaCode;
#JoinColumn(name = "country", referencedColumnName = "id")
#ManyToOne(optional = false)
private Country country;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
private Set<User> userSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
private Set<CardDetails> cardDetailsSet;
public Address() {
}
public Address(Integer id) {
this.id = id;
}
public Address(String line1, String line2, String city, String areaCode) {
this.line1 = line1;
this.line2 = line2;
this.city = city;
this.areaCode = areaCode;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLine1() {
return line1;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public String getLine2() {
return line2;
}
public void setLine2(String line2) {
this.line2 = line2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public Set<User> getUserSet() {
return userSet;
}
public void setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Set<CardDetails> getCardDetailsSet() {
return cardDetailsSet;
}
public void setCardDetailsSet(Set<CardDetails> cardDetailsSet) {
this.cardDetailsSet = cardDetailsSet;
}
#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 Address)) {
return false;
}
Address other = (Address) 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 "com.game.database.entity.Address[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "game")
#NamedQueries({
#NamedQuery(name = "Game.findAll", query = "SELECT g FROM Game g"),
#NamedQuery(name = "Game.findById", query = "SELECT g FROM Game g WHERE g.id = :id"),
#NamedQuery(name = "Game.findByHost", query = "SELECT g FROM Game g WHERE g.host = :host"),
#NamedQuery(name = "Game.findByPort", query = "SELECT g FROM Game g WHERE g.port = :port"),
#NamedQuery(name = "Game.findByDescription", query = "SELECT g FROM Game g WHERE g.description = :description"),
#NamedQuery(name = "Game.findByActive", query = "SELECT g FROM Game g WHERE g.active = :active"),
#NamedQuery(name = "Game.findByHostAndPort", query = "SELECT g FROM Game g WHERE g.host = :host AND g.port = :port") })
public class Game implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "game_id_seq", sequenceName = "game_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "game_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "host")
private String host;
#Basic(optional = false)
#Column(name = "port")
private int port;
#Basic(optional = false)
#Column(name = "description")
private String description;
#Basic(optional = false)
#Column(name = "active")
private Boolean active;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
private Set<Unit> unitSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
private Set<Payment> paymentSet;
public Game() {
}
public Game(Integer id) {
this.id = id;
}
public Game(String host, int port, String description, Boolean active) {
this.host = host;
this.port = port;
this.description = description;
this.active = active;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
public Set<Payment> getPaymentSet() {
return paymentSet;
}
public void setPaymentSet(Set<Payment> paymentSet) {
this.paymentSet = paymentSet;
}
#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 Game)) {
return false;
}
Game other = (Game) 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 "com.game.database.entity.Game[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "unit")
#NamedQueries({
#NamedQuery(name = "Unit.findAll", query = "SELECT u FROM Unit u"),
#NamedQuery(name = "Unit.findById", query = "SELECT u FROM Unit u WHERE u.id = :id"),
#NamedQuery(name = "Unit.findByUnitId", query = "SELECT u FROM Unit u WHERE u.unitId = :unitId"),
#NamedQuery(name = "Unit.findByName", query = "SELECT u FROM Unit u WHERE u.name = :name"),
#NamedQuery(name = "Unit.findByRegistrationDate", query = "SELECT u FROM Unit u WHERE u.registrationDate = :registrationDate"),
#NamedQuery(name = "Unit.findByService", query = "SELECT u FROM Unit u WHERE u.service = :service"),
#NamedQuery(name = "Unit.findByNation", query = "SELECT u FROM Unit u WHERE u.nation = :nation") })
public class Unit implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "unit_id_seq", sequenceName = "unit_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "unit_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "unitId")
private Integer unitId;
#Basic(optional = false)
#Column(name = "name")
private String name;
#Basic(optional = false)
#Column(name = "registrationDate")
#Temporal(TemporalType.TIMESTAMP)
private Date registrationDate;
#Basic(optional = false)
#Column(name = "service")
private String service;
#Basic(optional = false)
#Column(name = "nation")
private String nation;
#JoinColumn(name = "virtue", referencedColumnName = "id")
#ManyToOne(optional = false)
private Virtue virtue;
#JoinColumn(name = "customer", referencedColumnName = "id")
#ManyToOne(optional = false)
private User customer;
#JoinColumn(name = "game", referencedColumnName = "id")
#ManyToOne(optional = false)
private Game game;
public Unit() {
}
public Unit(Integer id) {
this.id = id;
}
public Unit(Integer unitId, String name, Date registrationDate,
String service, String nation) {
this.unitId = unitId;
this.name = name;
this.registrationDate = registrationDate;
this.service = service;
this.nation = nation;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUnitId() {
return unitId;
}
public void setUnitId(Integer unitId) {
this.unitId = unitId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public Virtue getVirtue() {
return virtue;
}
public void setVirtue(Virtue virtue) {
this.virtue = virtue;
}
public User getUser() {
return customer;
}
public void setUser(User user) {
this.customer = user;
}
public Game getGame() {
return game;
}
public void setGame(Game game) {
Logger.getLogger("org.hibernate").setLevel(Level.FINEST);
this.game = game;
}
#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 Unit)) {
return false;
}
Unit other = (Unit) 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 "com.game.database.entity.Unit[id=" + id + "]";
}
#Transient
private String command;
/**
* Get the value of command
*
* #return the value of command
*/
public String getCommand() {
return command;
}
/**
* Set the value of command
*
* #param command
* new value of command
*/
public void setCommand(String command) {
this.command = command;
}
#Transient
private String rank;
/**
* Get the value of rank
*
* #return the value of rank
*/
public String getRank() {
return rank;
}
/**
* Set the value of rank
*
* #param rank
* new value of rank
*/
public void setRank(String rank) {
this.rank = rank;
}
#Transient
private BigDecimal price;
/**
* Get the value of price
*
* #return the value of price
*/
public BigDecimal getPrice() {
return price;
}
/**
* Set the value of price
*
* #param price
* new value of price
*/
public void setPrice(BigDecimal price) {
this.price = price;
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "customer")
#NamedQueries({
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
#NamedQuery(name = "User.findByGivenName", query = "SELECT u FROM User u WHERE u.givenName = :givenName"),
#NamedQuery(name = "User.findBySurname", query = "SELECT u FROM User u WHERE u.surname = :surname"),
#NamedQuery(name = "User.findByPhoneNumber", query = "SELECT u FROM User u WHERE u.phoneNumber = :phoneNumber"),
#NamedQuery(name = "User.findBySex", query = "SELECT u FROM User u WHERE u.sex = :sex"),
#NamedQuery(name = "User.findByBirthYear", query = "SELECT u FROM User u WHERE u.birthYear = :birthYear"),
#NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email"),
#NamedQuery(name = "User.findByInfoSource", query = "SELECT u FROM User u WHERE u.infoSource = :infoSource"),
#NamedQuery(name = "User.findByOccupation", query = "SELECT u FROM User u WHERE u.occupation = :occupation"),
#NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password"),
#NamedQuery(name = "User.findByEmailAndPassword", query = "SELECT u FROM User u WHERE u.password = :password AND u.email = :email") })
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "givenName")
private String givenName;
#Basic(optional = false)
#Column(name = "surname")
private String surname;
#Basic(optional = false)
#Column(name = "phoneNumber")
private String phoneNumber;
#Basic(optional = false)
#Column(name = "sex")
private boolean sex;
#Basic(optional = false)
#Column(name = "birthYear")
#Temporal(TemporalType.DATE)
private Date birthYear;
#Basic(optional = false)
#Column(name = "email")
private String email;
#Basic(optional = false)
#Column(name = "infoSource")
private String infoSource;
#Basic(optional = false)
#Column(name = "occupation")
private String occupation;
#Basic(optional = false)
#Column(name = "password")
private String password;
/**
* The EAGER fetch type ensures that when we get access a unit remotely it
* has had its unit set initialised and populated
*/
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
private Set<Unit> unitSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
private Set<Payment> paymentSet;
#JoinColumn(name = "address", referencedColumnName = "id")
#ManyToOne(cascade = CascadeType.ALL, optional = false)
private Address address;
public User() {
}
public User(Integer id) {
this.id = id;
}
public User(String givenName, String surname, String phoneNumber,
boolean sex, Date birthYear, String email, String infoSource,
String occupation, String password) {
this.givenName = givenName;
this.surname = surname;
this.phoneNumber = phoneNumber;
this.sex = sex;
this.birthYear = birthYear;
this.email = email;
this.infoSource = infoSource;
this.occupation = occupation;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public Date getBirthYear() {
return birthYear;
}
public void setBirthYear(Date birthYear) {
this.birthYear = birthYear;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getInfoSource() {
return infoSource;
}
public void setInfoSource(String infoSource) {
this.infoSource = infoSource;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
public Set<Payment> getPaymentSet() {
return paymentSet;
}
public void setPaymentSet(Set<Payment> paymentSet) {
this.paymentSet = paymentSet;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
#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 User)) {
return false;
}
User other = (User) 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 "com.game.database.entity.User[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "virtue")
#NamedQueries({
#NamedQuery(name = "Virtue.findAll", query = "SELECT v FROM Virtue v"),
#NamedQuery(name = "Virtue.findById", query = "SELECT v FROM Virtue v WHERE v.id = :id"),
#NamedQuery(name = "Virtue.findByName", query = "SELECT v FROM Virtue v WHERE v.name = :name"),
#NamedQuery(name = "Virtue.findByDescription", query = "SELECT v FROM Virtue v WHERE v.description = :description") })
public class Virtue implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "virtue_id_seq", sequenceName = "virtue_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "virtue_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "name")
private String name;
#Basic(optional = false)
#Column(name = "description")
private String description;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "virtue")
private Set<Unit> unitSet;
public Virtue() {
}
public Virtue(Integer id) {
this.id = id;
}
public Virtue(String name, String description) {
this.name = name;
this.description = description;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
#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 Virtue)) {
return false;
}
Virtue other = (Virtue) 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 "com.game.database.entity.Virtue[id=" + id + "]";
}
}
You have a problem with the identity of the Unit objects. You're using in your code a HashSet which relies on equals and hashCode methods which are overridden in your code.
If you run the main method in the code below, you will see that after adding the Unit objects there is only one of them in the set (I reused your original code but I simplified it a bit):
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Unit {
private Integer id;
private Integer unitId;
private String name;
private Date registrationDate;
private String service;
private String nation;
public Unit() {
}
public Unit(Integer id) {
this.id = id;
}
public Unit(Integer unitId, String name, Date registrationDate, String service, String nation) {
this.unitId = unitId;
this.name = name;
this.registrationDate = registrationDate;
this.service = service;
this.nation = nation;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUnitId() {
return unitId;
}
public void setUnitId(Integer unitId) {
this.unitId = unitId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
#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 Unit)) {
return false;
}
Unit other = (Unit) 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 "com.game.database.entity.Unit[id=" + id + "]";
}
public static void main(String... args) {
Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService", "MyNation");
Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService", "TheirNation");
Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService", "TheirNation");
Set unitSet = new HashSet();
unitSet.add(unit2);
unitSet.add(unit1);
unitSet.add(unit3);
System.out.println(unitSet.size());
}
If you comment out the equals() and hashCode() and run the code again you will see three objects in the set.
Your equals() method is based on the id property which is set by hibernate at time the object is being persisted and not at the time of adding to the set. It means that the Unit has always a null id and hashCode = 0 when added to the set. I recommend reading this article: http://community.jboss.org/wiki/EqualsandHashCode
Hope it helps!