I have created a sessionFactory object from HibernateUtils as below
configuration.setProperty("connection.driver_class",prop.getProperty("driverClassName"));
configuration.setProperty("hibernate.connection.url",prop.getProperty("url"));
configuration.setProperty("hibernate.connection.username", prop.getProperty("username"));
configuration.setProperty("hibernate.connection.password", prop.getProperty("password"));
configuration.setProperty("hibernate.dialect", prop.getProperty("dialect"));
configuration.setProperty("hibernate.default_schema", prop.getProperty("schema"));
configuration.setProperty("hibernate.hbm2ddl.auto", "validate");
configuration.setProperty("packagesToScan", "daoBean");
I have a database where Test database and stock table is already created in this.
Now I am mapping a model object to insert the information.
#Entity
#Table(name = "stock", catalog = "mkyongdb", uniqueConstraints = {
#UniqueConstraint(columnNames = "STOCK_NAME"),
#UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
private Integer stockId;
private String stockCode;
private String stockName;
private StockDetail stockDetail;
public Stock() {
}
public Stock(String stockCode, String stockName) {
this.stockCode = stockCode;
this.stockName = stockName;
}
public Stock(String stockCode, String stockName, StockDetail stockDetail) {
this.stockCode = stockCode;
this.stockName = stockName;
this.stockDetail = stockDetail;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
#Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
public String getStockCode() {
return this.stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
#Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
public String getStockName() {
return this.stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "stock", cascade = CascadeType.ALL)
public StockDetail getStockDetail() {
return this.stockDetail;
}
public void setStockDetail(StockDetail stockDetail) {
this.stockDetail = stockDetail;
}
}
please suggest to map the stock object to insert data.
I got your pain point.
please add this line
configuration.addAnnotatedClass(Stock.class);
I think this will solve your problem.
Related
I have this two object Input and IndisponibleSegment with a relation one to many respectively:
#Entity
#Table(name= "input")
public class Input {
private long _id;
private String _name;
private Set<IndisponibleSegment> _indisponibleSegments;
#Column(name = "name", unique = true, nullable = false, length = 25)
public String getName() {
return _name;
}
public void setName(String inName) {
this._name = inName;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public long getId() {
return _id;
}
public void setId(long inId) {
this._id = inId;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "input", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<IndisponibleSegment> getIndisponibleSegments() {
return _indisponibleSegments;
}
public void setIndisponibleSegments(Set<IndisponibleSegment> inIndisponibleSegments) {
this._indisponibleSegments = inIndisponibleSegments;
}
}
And:
#Entity
#Table(name = "indisponible_segment")
public class IndisponibleSegment {
private Lane _lane;
private int _id;
private Input _input;
#ManyToOne(fetch=FetchType.EAGER)
#Cascade(value={org.hibernate.annotations.CascadeType.ALL})
#JoinColumn(name="input_id")
public Input getInput() {
return _input;
}
public void setInput(Input inInput) {
this._input = inInput;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id")
public int getId() {
return _id;
}
public void setId(int inId) {
this._id = inId;
}
#Enumerated(EnumType.STRING)
#Column(name = "lane", nullable = false)
public Lane getLane() {
return _lane;
}
public void setLane(Lane inLane) {
this._lane = inLane;
}
}
My problem is that everytime run a code like:
DAO dao = new DAO();
Input input = dao.get(Input.class, new Long(1));
if(input==null) {
input = new Input();
input.setName("Input 1");
}
Set<IndisponibleSegment> islist = new HashSet<>();
IndisponibleSegment is = new IndisponibleSegment();
is.setInput(input);
is.setLane(Lane.LANE_FAST);
islist.add(is);
input.setIndisponibleSegments(islist);
dao.saveOrUpdate(input);
I get a new entry in the indisponible_segments table and the old is not removed, thus still there.
I have tried all combinations I can think of: Cascade, delete-orphans, unique constranits... all. What am I doing wrong? All I want is that if I set a new the indisponibleSegments the old ones are deleted.
I'm using Hibernate and MySql and today I setted a composite primary key in one of my table, so below:
DefSelfLearning
And this entity is OneToMany with SelfLearning:
This is my java entity:
#Entity
#Table(name = "defselflearning", catalog = "ats")
public class DefSelfLearning implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EmbeddedId
private DefSelfLearningKeys defSelfLearningKeys;
private Ecu ecu;
private String excelColumn;
#JsonIgnore
private Set<SelfLearning> selfLearnings = new HashSet<SelfLearning>(0);
public DefSelfLearning() {
}
public DefSelfLearning(DefSelfLearningKeys defSelfLearningKeys, Ecu ecu) {
this.defSelfLearningKeys = defSelfLearningKeys;
this.ecu = ecu;
}
public DefSelfLearning(Ecu ecu, DefSelfLearningKeys defSelfLearningKeys, String excelColumn, Set<SelfLearning> selfLearnings) {
this.ecu = ecu;
this.defSelfLearningKeys = defSelfLearningKeys;
this.excelColumn = excelColumn;
this.selfLearnings = selfLearnings;
}
#Id
public DefSelfLearningKeys getDefSelfLearningKeys() {
return this.defSelfLearningKeys;
}
public void setDefSelfLearningKeys(DefSelfLearningKeys defSelfLearningKeys) {
this.defSelfLearningKeys = defSelfLearningKeys;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_ecu", nullable = false)
public Ecu getEcu() {
return this.ecu;
}
public void setEcu(Ecu ecu) {
this.ecu = ecu;
}
#Column(name = "excelColumn", length = 2)
public String getExcelColumn() {
return this.excelColumn;
}
public void setExcelColumn(String excelColumn) {
this.excelColumn = excelColumn;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "defSelfLearning")
public Set<SelfLearning> getSelfLearnings() {
return this.selfLearnings;
}
public void setSelfLearnings(Set<SelfLearning> selfLearnings) {
this.selfLearnings = selfLearnings;
}
}
the class for the composite key:
#Embeddable
public class DefSelfLearningKeys implements Serializable {
private static final long serialVersionUID = 1L;
protected String parName;
protected String description;
protected String note;
public DefSelfLearningKeys() {}
public DefSelfLearningKeys(String parName, String description, String note) {
this.parName = parName;
this.description = description;
this.note = note;
}
#Column(name = "parName", nullable = false, length = 15)
public String getParName() {
return this.parName;
}
public void setParName(String parName) {
this.parName = parName;
}
#Column(name = "description", nullable = false, length = 100)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "note", nullable = false, length = 100)
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
}
and SelfLearning class:
#Entity
#Table(name = "selflearning", catalog = "ats")
public class SelfLearning implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idSelfLearning;
private Acquisition acquisition;
private DefSelfLearning defSelfLearning;
private String value;
public SelfLearning() {
}
public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning) {
this.idSelfLearning = idSelfLearning;
this.acquisition = acquisition;
this.defSelfLearning = defSelfLearning;
}
public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning, String value) {
this.idSelfLearning = idSelfLearning;
this.acquisition = acquisition;
this.defSelfLearning = defSelfLearning;
this.value = value;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_selfLearning", unique = true, nullable = false)
public int getIdSelfLearning() {
return this.idSelfLearning;
}
public void setIdSelfLearning(int idSelfLearning) {
this.idSelfLearning = idSelfLearning;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_acquisition", nullable = false)
public Acquisition getAcquisition() {
return this.acquisition;
}
public void setAcquisition(Acquisition acquisition) {
this.acquisition = acquisition;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "id_parName", nullable = false),
#JoinColumn(name = "id_description", nullable = false),
#JoinColumn(name = "id_note", nullable = false)
})
public DefSelfLearning getDefSelfLearning() {
return this.defSelfLearning;
}
public void setDefSelfLearning(DefSelfLearning defSelfLearning) {
this.defSelfLearning = defSelfLearning;
}
#Column(name = "value")
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}
but when I create a defSelfLearning all work fine, but when I create a SelfLearning I receive MysqlDataTruncation exception:
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'id_parName' at row 1
This error is enough explined, but I don't find where is the problem, this is the code for SelfLearning creation:
for (DefSelfLearning defSelfLearning:defSelfLearningList){
SelfLearning selfLearning=new SelfLearning();
String key = defSelfLearning.getExcelColumn()+index;
String value = actualRowValues.get(key);
selfLearning.setAcquisition(findByCarAndExcelRow(carServices.findById(acquisitionForm.getCar()), index));
selfLearning.setDefSelfLearning(defSelfLearning);
selfLearning.setValue(value);
System.out.println(selfLearning.getDefSelfLearning().getDefSelfLearningKeys().getParName());
selfLearningServices.create(selfLearning);
}
Do you find where is the problem?Thanks
This is the first row of defSelfLearning and it's where the code fails
if I set manually this it works:
This is a screen of java debug of first code, that fails:
You try to insert a char which is longer than 15 in the column "id_parName"
On your Entities, you have to choose between field and getter. And all the annotations should be on fields, or they should all be on getters, you can't mix both approaches (except if you use the #AccessType annotation).
Hibernate / Jpa will pick up the used approch from the annotation on Id.
Change #Id on the first Embeddable entity to #EmbeddedId and make sure it is on the getter.
SelfLearning wrong mappings the columns, id_parName= id_description, id_description= id_note and id_note=id_parName, but why?
So I read:
When the JoinColumns annotation is used, both the name and the
referencedColumnName elements must be specified in each such
JoinColumn annotation.
I have added this element so:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "id_parName", referencedColumnName="parName", nullable = false),
#JoinColumn(name = "id_description", referencedColumnName="description", nullable = false),
#JoinColumn(name = "id_note", referencedColumnName="note", nullable = false)
})
public DefSelfLearning getDefSelfLearning() {
return this.defSelfLearning;
}
And it works
I have this bean that is auto-generated from DB:
#Entity
#Table(name = "richiesta", catalog = "gestione_utenza")
public class Richiesta implements java.io.Serializable {
private Integer idRichiesta;
private MessaggiErrore messaggiErrore;
private Stato stato;
private Date dataInserimento;
private Date dataElaborazione;
private String nota;
private String usernameAssegnato;
private String utenteAutorizzante;
private String urlattivazione;
private Anagrafica anagrafica;
private Set<RichiestaApplicazione> richiestaApplicaziones = new HashSet<RichiestaApplicazione>(
0);
public Richiesta() {
}
public Richiesta(Stato stato, Date dataInserimento) {
this.stato = stato;
this.dataInserimento = dataInserimento;
}
public Richiesta(MessaggiErrore messaggiErrore, Stato stato,
Date dataInserimento, Date dataElaborazione, String nota,
String usernameAssegnato, String utenteAutorizzante,
String urlattivazione, Anagrafica anagrafica,
Set<RichiestaApplicazione> richiestaApplicaziones) {
this.messaggiErrore = messaggiErrore;
this.stato = stato;
this.dataInserimento = dataInserimento;
this.dataElaborazione = dataElaborazione;
this.nota = nota;
this.usernameAssegnato = usernameAssegnato;
this.utenteAutorizzante = utenteAutorizzante;
this.urlattivazione = urlattivazione;
this.anagrafica = anagrafica;
this.richiestaApplicaziones = richiestaApplicaziones;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "idRichiesta", unique = true, nullable = false)
public Integer getIdRichiesta() {
return this.idRichiesta;
}
public void setIdRichiesta(Integer idRichiesta) {
this.idRichiesta = idRichiesta;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "codiceErrore")
public MessaggiErrore getMessaggiErrore() {
return this.messaggiErrore;
}
public void setMessaggiErrore(MessaggiErrore messaggiErrore) {
this.messaggiErrore = messaggiErrore;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "stato", nullable = false)
public Stato getStato() {
return this.stato;
}
public void setStato(Stato stato) {
this.stato = stato;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "dataInserimento", nullable = false, length = 19)
public Date getDataInserimento() {
return this.dataInserimento;
}
public void setDataInserimento(Date dataInserimento) {
this.dataInserimento = dataInserimento;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "dataElaborazione", length = 19)
public Date getDataElaborazione() {
return this.dataElaborazione;
}
public void setDataElaborazione(Date dataElaborazione) {
this.dataElaborazione = dataElaborazione;
}
#Column(name = "nota", length = 256)
public String getNota() {
return this.nota;
}
public void setNota(String nota) {
this.nota = nota;
}
#Column(name = "usernameAssegnato", length = 20)
public String getUsernameAssegnato() {
return this.usernameAssegnato;
}
public void setUsernameAssegnato(String usernameAssegnato) {
this.usernameAssegnato = usernameAssegnato;
}
#Column(name = "utenteAutorizzante", length = 20)
public String getUtenteAutorizzante() {
return this.utenteAutorizzante;
}
public void setUtenteAutorizzante(String utenteAutorizzante) {
this.utenteAutorizzante = utenteAutorizzante;
}
#Column(name = "URLattivazione", length = 80)
public String getUrlattivazione() {
return this.urlattivazione;
}
public void setUrlattivazione(String urlattivazione) {
this.urlattivazione = urlattivazione;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "richiesta")
public Anagrafica getAnagrafica() {
return this.anagrafica;
}
public void setAnagrafica(Anagrafica anagrafica) {
this.anagrafica = anagrafica;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "richiesta")
public Set<RichiestaApplicazione> getRichiestaApplicaziones() {
return this.richiestaApplicaziones;
}
public void setRichiestaApplicaziones(
Set<RichiestaApplicazione> richiestaApplicaziones) {
this.richiestaApplicaziones = richiestaApplicaziones;
}
}
I want to add a new Richiesta, with his childs, but with the code that I wrote I'm able to add only a new row in the table Richiesta:
Richiesta ric = new Richiesta();
Stato st = new Stato();
st.setIdStato(1);
ric.setStato(st);
ric.setDataInserimento(new Date());
Integer[] appId = getApplicazioniSelezionateDefault();
for (int k=0; k<appId.length; k++)
{
Applicazione ap = new Applicazione();
ap.setIdApplicazione(appId[k]);
ric.getRichiestaApplicaziones().add( new RichiestaApplicazione( ap, ric));
}
Ufficio uf = new Ufficio();
uf.setIdufficio(this.getUfficioVDR());
Qualifica qu = new Qualifica();
qu.setIdQualifica( CommonUtil.getIndexInteger(getQualificaSelezionataVDR()) );
ric.setAnagrafica(new Anagrafica(uf, qu, ric, getCognomeVDR(), getNomeVDR(), getDataNascitaVDR(), getTelefonoVDR(), getEmailVDR(), getIpVDR()));
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(ric);
session.getTransaction().commit();
I would like to have a new row in the table Anagrafica, and "N" news rows in the table RichiestaApplicazione.
#Entity
#Table(name = "anagrafica", catalog = "gestione_utenza")
public class Anagrafica implements java.io.Serializable {
private Integer idRichiesta;
private Ufficio ufficio;
private Qualifica qualifica;
private Richiesta richiesta;
private String cognome;
private String nome;
private Date dataNascita;
private String telefono;
private String email;
private String ip;
[...]
#GenericGenerator(name = "generator", strategy = "foreign", parameters = #Parameter(name = "property", value = "richiesta"))
#Id
#GeneratedValue(generator = "generator")
#Column(name = "idRichiesta", unique = true, nullable = false)
public Integer getIdRichiesta() {
return this.idRichiesta;
}
[...]
}
I read to add the CASCADE attribute to the xml/annotation, is it possible to make it without editing annotation/xml? For example adding something in the code.
To become persistent, a new entity instance must be added to the persistent context with session.persist(newEntity) or session.save(newEntity). You haven't called this method on anything except ric. So all the other created entities are still not persistent.
i have a program that communicates with an existing database. There is a composite table that has an employee and a vehicle as its composite key. On the edit or add employee page, their is a dropdown box to select which vehicles the employee prefers and then stores the vehicle list in a hashtable in the employee class. However, the list will not persist, or store, in the composite table. I am new to seam and have spent all day trying to figure this out. Any help would be appreciated.
Here are some of my classes:
Employee:
#Entity
#Table(name = "flower_store_employee", schema = "dbo", catalog = "tyler")
public class FlowerStoreEmployee implements java.io.Serializable, Comparable<FlowerStoreEmployee> {
/**
*
*/
private static final long serialVersionUID = -1727355085366851150L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "employee_id", unique = true, nullable = false)
private Integer employeeId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "address_id")
private FlowerStoreAddress flowerStoreAddress;
#Column(name = "name_first", length = 25)
#Length(max = 25)
private String nameFirst;
#Column(name = "name_last", length = 25)
#Length(max = 25)
private String nameLast;
#Column(name = "ssn")
private String ssn;
#Column(name = "phone")
private String phone;
#Column(name = "pay")
private int pay;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreEmployee")
private Set<FlowerStoreDelivery> flowerStoreDeliveries = new HashSet<FlowerStoreDelivery>(
0);
#Cascade({org.hibernate.annotations.CascadeType.ALL })
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreEmployees")
//#JoinTable(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler", joinColumns = { #JoinColumn(name = "vehicle_id", nullable = false, updatable = true) }, inverseJoinColumns = { #JoinColumn(name = "employee_id", nullable = false, updatable = true) })
private Set<FlowerStoreVehicle> flowerStoreVehicles = new HashSet<FlowerStoreVehicle>(
0);
public FlowerStoreEmployee() {
}
public FlowerStoreEmployee(int employeeId) {
this.employeeId = employeeId;
}
public FlowerStoreEmployee(FlowerStoreAddress flowerStoreAddress, String nameFirst,
String nameLast, String ssn, String phone, int pay,
Set<FlowerStoreDelivery> flowerStoreDeliveries,
Set<FlowerStoreVehicle> flowerStoreVehicles) {
this.employeeId = employeeId;
this.flowerStoreAddress = flowerStoreAddress;
this.nameFirst = nameFirst;
this.nameLast = nameLast;
this.ssn = ssn;
this.phone = phone;
this.pay = pay;
this.flowerStoreDeliveries = flowerStoreDeliveries;
this.flowerStoreVehicles = flowerStoreVehicles;
}
public int getEmployeeId() {
return this.employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public FlowerStoreAddress getFlowerStoreAddress() {
return this.flowerStoreAddress;
}
public void setFlowerStoreAddress(FlowerStoreAddress flowerStoreAddress) {
this.flowerStoreAddress = flowerStoreAddress;
}
public String getNameFirst() {
return this.nameFirst;
}
public void setNameFirst(String nameFirst) {
this.nameFirst = nameFirst;
}
public String getNameLast() {
return this.nameLast;
}
public void setNameLast(String nameLast) {
this.nameLast = nameLast;
}
public String getSsn() {
return this.ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getPay() {
return this.pay;
}
public void setPay(int pay) {
this.pay = pay;
}
public void setPay(String pay){
this.pay = Integer.parseInt(pay);
}
public Set<FlowerStoreDelivery> getFlowerStoreDeliveries() {
return this.flowerStoreDeliveries;
}
public void setFlowerStoreDeliveries(
Set<FlowerStoreDelivery> flowerStoreDeliveries) {
this.flowerStoreDeliveries = flowerStoreDeliveries;
}
public Set<FlowerStoreVehicle> getFlowerStoreVehicles() {
return this.flowerStoreVehicles;
}
public void setFlowerStoreVehicles(
Set<FlowerStoreVehicle> flowerStoreVehicles) {
this.flowerStoreVehicles = flowerStoreVehicles;
}
public int compareTo(FlowerStoreEmployee emp) {
if(this.employeeId > emp.employeeId){
return 1;
}
else
if(this.employeeId < emp.employeeId){
return -1;
}
else{
return 0;
}
}
Vehicle:
#Entity
#Table(name = "flower_store_vehicle", schema = "dbo", catalog = "tyler")
public class FlowerStoreVehicle implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 5349431404739349258L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "vehicle_id", unique = true, nullable = false)
private int vehicleId;
#Column(name = "vin", length = 17)
#Length(max = 17)
private String vin;
#Column(name = "license", length = 10)
#Length(max = 10)
private String license;
#Column(name = "make", length = 15)
#Length(max = 15)
private String make;
#Column(name = "model", length = 20)
#Length(max = 20)
private String model;
#Column(name = "color", length = 20)
#Length(max = 20)
private String color;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreVehicle")
private Set<FlowerStoreDelivery> flowerStoreDeliveries = new HashSet<FlowerStoreDelivery>(
0);
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler", joinColumns = { #JoinColumn(name = "vehicle_id", nullable = false, updatable = false) }, inverseJoinColumns = { #JoinColumn(name = "employee_id", nullable = false, updatable = false) })
private Set<FlowerStoreEmployee> flowerStoreEmployees = new HashSet<FlowerStoreEmployee>(
0);
public FlowerStoreVehicle() {
}
public FlowerStoreVehicle(int vehicleId) {
this.vehicleId = vehicleId;
}
public FlowerStoreVehicle(int vehicleId, String vin, String license,
String make, String model, String color,
Set<FlowerStoreDelivery> flowerStoreDeliveries,
Set<FlowerStoreEmployee> flowerStoreEmployees) {
this.vehicleId = vehicleId;
this.vin = vin;
this.license = license;
this.make = make;
this.model = model;
this.color = color;
this.flowerStoreDeliveries = flowerStoreDeliveries;
this.flowerStoreEmployees = flowerStoreEmployees;
}
public int getVehicleId() {
return this.vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVin() {
return this.vin;
}
public void setVin(String vin) {
this.vin = vin;
}
public String getLicense() {
return this.license;
}
public void setLicense(String license) {
this.license = license;
}
public String getMake() {
return this.make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return this.model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return this.color;
}
public void setColor(String color) {
this.color = color;
}
public Set<FlowerStoreDelivery> getFlowerStoreDeliveries() {
return this.flowerStoreDeliveries;
}
public void setFlowerStoreDeliveries(
Set<FlowerStoreDelivery> flowerStoreDeliveries) {
this.flowerStoreDeliveries = flowerStoreDeliveries;
}
public Set<FlowerStoreEmployee> getFlowerStoreEmployees() {
return this.flowerStoreEmployees;
}
public void setFlowerStoreEmployees(
Set<FlowerStoreEmployee> flowerStoreEmployees) {
this.flowerStoreEmployees = flowerStoreEmployees;
}
}
CompositeTableID:
/**
* FlowerStoreEmpVehicleId generated by hbm2java
*/
#Embeddable
public class FlowerStoreEmpVehicleId implements java.io.Serializable {
private int vehicleId;
private int employeeId;
public FlowerStoreEmpVehicleId() {
}
public FlowerStoreEmpVehicleId(int vehicleId, int employeeId) {
this.vehicleId = vehicleId;
this.employeeId = employeeId;
}
#Column(name = "vehicle_id", nullable = false)
public int getVehicleId() {
return this.vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
#Column(name = "employee_id", nullable = false)
public int getEmployeeId() {
return this.employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof FlowerStoreEmpVehicleId))
return false;
FlowerStoreEmpVehicleId castOther = (FlowerStoreEmpVehicleId) other;
return (this.getVehicleId() == castOther.getVehicleId())
&& (this.getEmployeeId() == castOther.getEmployeeId());
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getVehicleId();
result = 37 * result + this.getEmployeeId();
return result;
}
}
CompositeTable:
#Entity
#Table(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler")
public class FlowerStoreEmpVehicle implements java.io.Serializable {
private FlowerStoreEmpVehicleId id;
public FlowerStoreEmpVehicle() {
}
public FlowerStoreEmpVehicle(FlowerStoreEmpVehicleId id) {
this.id = id;
}
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "vehicleId", column = #Column(name = "vehicle_id", nullable = false)),
#AttributeOverride(name = "employeeId", column = #Column(name = "employee_id", nullable = false)) })
#NotNull
public FlowerStoreEmpVehicleId getId() {
return this.id;
}
public void setId(FlowerStoreEmpVehicleId id) {
this.id = id;
}
}
and here is the code to save the employee:
public String addEmployee(){
Set<FlowerStoreVehicle> vehicleSet = new HashSet<FlowerStoreVehicle>();
FlowerStoreEmployee n = new FlowerStoreEmployee();
if(first!=null && first!=""){
n.setNameFirst(first);
}
if(last!=null && last!=""){
n.setNameLast(last);
}
if(pay!=null && pay!=""){
int intPay = (int)(Double.parseDouble(pay)*100);
n.setPay(intPay);
}
if(phone!=null && phone!=""){
n.setPhone(phone);
}
if(ssn!=null && ssn!=""){
n.setSsn(ssn);
}
if(vehicle!=null && vehicle!=""){
String[] vehStr = vehicle.split(" ");
for(int i = 0; i < vehStr.length; i++){
int vehId = Integer.parseInt(vehStr[i]);
vehicleSet.add(entityManager.find(FlowerStoreVehicle.class, vehId));
}
}
if(!vehicleSet.isEmpty()){
n.setFlowerStoreVehicles(vehicleSet);
}
entityManager.persist(n);
if(zip!=null && zip!=""){
FlowerStoreZip zipCode = entityManager.find(FlowerStoreZip.class, Integer.parseInt(zip));
if(zipCode==null){
zipCode = new FlowerStoreZip();
if(zip!=null && zip!=""){
zipCode.setZipCode(Integer.parseInt(zip));
}
if(city!=null && city!=""){
zipCode.setCity(city);
}
if(state!=null && city!=""){
zipCode.setState(state);
}
entityManager.persist(zipCode);
}
}
FlowerStoreAddress add = new FlowerStoreAddress();
if(house!=null && house!=""){
add.setHouseNumber(Integer.parseInt(house));
}
if(street!=null && street!=""){
add.setStreet(street);
}
if(zip!=null && zip!=""){
add.setFlowerStoreZip(entityManager.find(FlowerStoreZip.class, Integer.parseInt(zip)));
}
return "/employee.xhtml";
}
If any more info is needed please let me know. Any help will be greatly appreciated. thank you
First of all, check your code, you have a lot of buggy instructions: in Java you compare Strings with the equals() method, not like this: ssn != "".
The root of your problem is not Seam itself but Hibernate. First of all, add elements to the vehicle set via n.getFlowerStoreVehicles().add(...), don't reassign the entire set with n.setFlowerStoreVehicles(...) (this is probably not a problem during entity creation but becomes a problem when modifying the set after the entities are persisted.
The reason for the relationship not being correctly persisted is that FlowerStoreEmployee is the "weak" side of the relationship (the one with the "mappedBy" attribute in the annotation). Move the #JoinTable annotation to the FlowerStoreEmployee class and remove it from FlowerStoreVehicle, remove the mappedBy from FlowerStoreEmployee and put it in the FlowerStoreVehicle (mappedBy="flowerStoreVehicles"). Since the relationship is bi-directional, assign to both sides of the relationship:
FlowerStoreVehicle veh = entityManager.find(FlowerStoreVehicle.class, vehId);
veh.getFlowerStoreEmployees().add(n); // one direction: vehicle -> employee
n.getFlowerStoreVehicles().add(veh); // the other direction: employee -> vehicle
There is no entityManager.persist at the end of your code, apart from persisting the ZipCode no Object is persisted.
I have problem with validation a very specific beans.
Let me give you some code first:
#Entity
#Table(name = "customers", schema = "public", uniqueConstraints = #UniqueConstraint(columnNames = {"cus_email" }))
public class Customers extends ModelObject implements java.io.Serializable {
private static final long serialVersionUID = -3197505684643025341L;
private long cusId;
private String cusEmail;
private String cusPassword;
private Addresses shippingAddress;
private Addresses invoiceAddress;
#Id
#Column(name = "cus_id", unique = true, nullable = false)
#SequenceGenerator(name = "cus_seq", sequenceName = "customers_cus_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cus_seq")
#NotNull
public long getCusId() {
return cusId;
}
public void setCusId(long cusId) {
this.cusId = cusId;
}
#NotEmpty
#Size(min=5, max=255)
#Email
#Column(name = "cus_email", unique = true, nullable = false, length = 255)
public String getCusEmail() {
return cusEmail;
}
public void setCusEmail(String cusEmail) {
this.cusEmail = cusEmail;
}
#NotNull
#Column(name = "cus_password", nullable = false)
public String getCusPassword() {
return cusPassword;
}
public void setCusPassword(String cusPassword) {
this.cusPassword = cusPassword;
}
#NotNull
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "cus_shipping_adr_id", nullable = false)
#Cascade(value = CascadeType.ALL)
#Valid
public Addresses getShippingAddress() {
return shippingAddress;
}
public void setShippingAddress(Addresses cusShippingAddress) {
this.shippingAddress = cusShippingAddress;
}
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "cus_invoice_adr_id", nullable = true)
#Cascade(value = CascadeType.ALL)
#Valid
public Addresses getInvoiceAddress() {
return invoiceAddress;
}
public void setInvoiceAddress(Addresses cusInvoiceAddress) {
this.invoiceAddress = cusInvoiceAddress;
}
}
As you can see, I have here two address fields - one for shipping address, the other for invoice address.
The validation for each type of address should be different, as e.g. I don't need VAT number in shipping address, but I may want that in invoice.
I used groups to perform different validation on invoice address and shipping address which works OK if I do manual validation of address field.
But now I'd like to validate whole Customer object with addresses (if available).
I tried to do that with code below:
private void validateCustomerData() throws CustomerValidationException {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Customers>> constraintViolations;
constraintViolations = validator.validate(customer, Default.class, InvoiceAddressCheck.class, ShippingAddressCheck.class);
if (!constraintViolations.isEmpty()) {
throw new CustomerValidationException(3, Message.CustomerDataException, constraintViolations);
}
}
Of course this doesn't work as it supposed, since both validations are run on both instances of address objects inside customer object, so I get errors in shipping address from InvoiceAddressCheck interface and errors in invoice address from ShippingAddressCheck.
Here is shortened declaration of Addresses bean:
#Entity
#Table(name = "addresses", schema = "public")
#TypeDef(name = "genderConverter", typeClass = GenderConverter.class)
public class Addresses extends ModelObject implements Serializable{
private static final long serialVersionUID = -1123044739678014182L;
private long adrId;
private String street;
private String houseNo;
private String zipCode;
private String state;
private String countryCode;
private String vatNo;
private Customers customersShipping;
private Customers customersInvoice;
public Addresses() {}
public Addresses(long adrId) {
super();
this.adrId = adrId;
}
#Id
#Column(name = "adr_id", unique = true, nullable = false)
#SequenceGenerator(name = "adr_seq", sequenceName = "adr_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "adr_seq")
#NotNull
public long getAdrId() {
return adrId;
}
public void setAdrId(long adrId) {
this.adrId = adrId;
}
#NotNull
#Column(name = "adr_street", nullable = false)
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
#NotEmpty(groups = ShippingAddressCheck.class)
#Column(name = "adr_house_no")
public String getHouseNo() {
return houseNo;
}
#NotEmpty(groups = ShippingAddressCheck.class)
#Column(name = "adr_zip_code")
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
#Column(name = "adr_vat_no")
#NotEmpty(groups = InvoiceAddressCheck.class)
public String getVatNo() {
return vatNo;
}
public void setVatNo(String vatNo) {
this.vatNo = vatNo;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "shippingAddress")
public Customers getCustomersShipping() {
return customersShipping;
}
public void setCustomersShipping(Customers customersShipping) {
this.customersShipping = customersShipping;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "invoiceAddress")
public Customers getCustomersInvoice() {
return customersInvoice;
}
public void setCustomersInvoice(Customers customersInvoice) {
this.customersInvoice = customersInvoice;
}
}
Is there any way to run the validation, so that invoiceAddress is validated with InvoiceAddressCheck group and shippingAddress validated with ShippingAddressCheck group, but run during validation of Customer object?
I know that I can do it manually for each subobject, but that is not the point in here.
Temp solution for now is to write custom validation for invoice field, so it checks only InvoiceAddressCheck.
Here is the code I have
Annotation:
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Constraint(validatedBy = {InvoiceAddressValidator.class })
public #interface InvoiceAddressChecker {
String message() default "Invoice address incorrect.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Validator:
public class InvoiceAddressValidator implements ConstraintValidator<InvoiceAddressChecker, Addresses> {
#Override
public void initialize(InvoiceAddressChecker params) {
}
#Override
public boolean isValid(Addresses invoiceAddress, ConstraintValidatorContext context) {
// invoice address is optional
if (invoiceAddress == null) {
return true;
}
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Addresses>> constraintViolations;
constraintViolations = validator.validate(invoiceAddress, Default.class, InvoiceAddressCheck.class);
if (constraintViolations.isEmpty()) {
return true;
} else {
context.disableDefaultConstraintViolation();
Iterator<ConstraintViolation<Addresses>> iter = constraintViolations.iterator();
while (iter.hasNext()) {
ConstraintViolation<Addresses> violation = iter.next();
context.buildConstraintViolationWithTemplate(violation.getMessage()).addNode(
violation.getPropertyPath().toString()).addConstraintViolation();
}
return false;
}
}
}
And model annotation:
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "cus_invoice_adr_id", nullable = true)
#Cascade(value = CascadeType.ALL)
#InvoiceAddressChecker
public Addresses getInvoiceAddress() {
return invoiceAddress;
}
It's not really great solution, but it does what I need.
If you figure out better solution, please let me know :)