I have a class (Vehicles) and I implemented CRUD operations. Delete works, update works, just create doesn't work.
What can I put instead of this create code?
P.S.: I use Eclipse
AND THIS IS FormMasini.java where I take from Vehicule.java dates and it will show in a JSF Form. The error appears at this line: this.vehicul = new Vehicul();
package vehiculeFeaa;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
#Entity
#Table(name = "VEHICUL")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "VEHICUL_TYPE")
public abstract class Vehicul {
#TableGenerator(name = "VEHICUL_GEN", table = "ID_GEN", pkColumnName = "GEN_NUME", valueColumnName = "GEN_VALOARE", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "VEHICUL_GEN")
private int idVehicul;
private String producator;
public int getIdVehicul() {
return idVehicul;
}
public void setIdVehicul(int idVehicul) {
this.idVehicul = idVehicul;
}
public String getProducator() {
return producator;
}
public void setProducator(String producator) {
this.producator = producator;
}
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
public List<Vehicul> get(int i) {
// TODO Auto-generated method stub
return null;
}
}
package masinifeaa;
import java.util.ArrayList;
import java.util.List;
import javax.faces.event.ActionEvent;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import vehiculeFeaa.Vehicul;
public class FormMasini {
private Vehicul vehicul;
private List<Vehicul>vehicule=new ArrayList<Vehicul>();
public Vehicul getVehicul() {
return vehicul;
}
public void setVehicul(Vehicul vehicul) {
this.vehicul = vehicul;
}
public List<Vehicul> getVehicule() {
return vehicule;
}
public void setVehicule(List<Vehicul> vehicule) {
this.vehicule = vehicule;
}
private EntityManager em;
#SuppressWarnings("unchecked")
public FormMasini() {
EntityManagerFactory emf=
Persistence.createEntityManagerFactory("FirmeJPA");
em=emf.createEntityManager();
this.vehicule= em.createQuery("SELECT v FROM Vehicul v")
.getResultList();
if(!this.vehicule.isEmpty())
vehicul=this.vehicule.get(0);
}
public void backVehicul(ActionEvent evt) {
Integer idxCurent = this.vehicule.indexOf(vehicul);
if(idxCurent > 0)
this.vehicul=this.vehicule.get(idxCurent-1);
}
public void nextVehicul(ActionEvent evt) {
Integer idxCurent = this.vehicule.indexOf(vehicul);
if((idxCurent + 1) < this.vehicule.size())
this.vehicul=this.vehicule.get(idxCurent + 1);
}
//Implementez actiunile CRUD
public void deleteVehicul(ActionEvent evt) {
this.vehicule.remove(this.vehicul);
if(this.em.contains(this.vehicul)) {
this.em.getTransaction().begin();
this.em.remove(this.vehicul);
this.em.getTransaction().commit();
}
if(!this.vehicule.isEmpty())
this.vehicul=this.vehicule.get(0);
else
this.vehicul=null;
}
public void saveVehicul(ActionEvent evt) {
this.em.getTransaction().begin();
this.em.persist(this.vehicul);
this.em.getTransaction().commit();
}
public void abandonVehicul(ActionEvent evt) {
if(this.em.contains(this.vehicul))
this.em.refresh(this.vehicul);
}
public void createVehicul(ActionEvent evt) {
this.vehicul = new Vehicul();
this.vehicul.setidVehicul(999);
this.vehicul.setNume("New car");
this.vehicule.add(this.vehicul);
}
Nothing related to JSF or something else. You just can't instantiate a abstract class, thats basic java.
Related
I have developped a Spring boot application that was using fetch = EAGER annotation on all relationships between entities. I think this is causing severe performance issues and I've since learned that it is seemingly an anti-pattern (https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ & https://vladmihalcea.com/eager-fetching-is-a-code-smell/).
I've been trying to figure out how to use lazy loading properly. I've come up with a minimal example that allows me to reproduce it.
TestJpaApplication
package com.myproject.testJpa;
import com.myproject.testJpa.entity.Host;
import com.myproject.testJpa.entity.HostSet;
import com.myproject.testJpa.entity.repository.HostRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.myproject.testJpa.entity.repository.HostSetRepository;
import org.springframework.transaction.annotation.Transactional;
#SpringBootApplication
public class TestJpaApplication {
private final Logger logger = LoggerFactory.getLogger(TestJpaApplication.class);
#Autowired
private HostRepository hostRepository;
#Autowired
private HostSetRepository hostSetRepository;
public static void main(String[] args) {
SpringApplication.run(TestJpaApplication.class, args);
}
#Bean
public CommandLineRunner demo() {
return (args) -> {
init();
fetch();
};
}
private void init() {
Host host1 = findOrCreateHost("HOST 1");
Host host2 = findOrCreateHost("HOST 2");
Host host3 = findOrCreateHost("HOST 3");
HostSet hostSet = findOrCreateHostSet("HOST SET 1");
hostSet.addHost(host1);
hostSetRepository.save(hostSet);
hostRepository.save(host1);
hostRepository.save(host2);
hostRepository.save(host3);
}
#Transactional
private void fetch() {
HostSet hostSet = hostSetRepository.findOneByNameIgnoreCase("HOST SET 1");
for(Host host : hostSet.getHosts()) {
logger.debug("Host: {}", host);
}
}
public Host findOrCreateHost(String name) {
Host host = hostRepository.findOneByNameIgnoreCase(name);
if(host == null) {
host = new Host(name);
hostRepository.save(host);
}
return host;
}
public HostSet findOrCreateHostSet(String name) {
HostSet hostSet = hostSetRepository.findOneByNameIgnoreCase(name);
if (hostSet == null) {
hostSet = new HostSet(name);
hostSetRepository.save(hostSet);
}
logger.debug("Host: {}", hostSet.getHosts());
return hostSet;
}
}
Host
package com.myproject.testJpa.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
#Entity
public class Host {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "host__id")
private Long id;
private String name;
#ManyToMany(mappedBy = "hosts")
private Set<HostSet> hostSets = new HashSet<>();
public Host() {
}
public Host(Long id) {
this.id = id;
}
public Host(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<HostSet> getHostSets() {
return hostSets;
}
public void setHostSets(Set<HostSet> hostSets) {
this.hostSets = hostSets;
hostSets.forEach(hs -> addToHostSet(hs));
}
public Host addToHostSet(HostSet hostSet) {
if (!hostSets.contains(hostSet)) {
hostSets.add(hostSet);
hostSet.getHosts().add(this);
}
return this;
}
public Host removeFromHostSet(HostSet hostSet) {
if (hostSets.contains(hostSet)) {
hostSets.remove(hostSet);
hostSet.getHosts().remove(this);
}
return this;
}
}
HostSet
package com.myproject.testJpa.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
#Entity
public class HostSet {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "host_set__id")
private Long id;
private String name;
#ManyToMany
#JoinTable(
name = "host_set__host",
joinColumns = #JoinColumn(name = "host_set__id"),
inverseJoinColumns = #JoinColumn(name = "host__id")
)
private Set<Host> hosts = new HashSet<>();
public HostSet() {
}
public HostSet(Long id) {
this.id = id;
}
public HostSet(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Host> getHosts() {
return hosts;
}
public void setHosts(Set<Host> hosts) {
this.hosts = hosts;
}
public HostSet addHost(Host host) {
if(!hosts.contains(host)) {
hosts.add(host);
host.addToHostSet(this);
}
return this;
}
public HostSet removeHost(Host host) {
if(hosts.contains(host)) {
hosts.remove(host);
host.removeFromHostSet(this);
}
return this;
}
}
HostRepository
package com.myproject.testJpa.entity.repository;
import com.myproject.testJpa.entity.Host;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface HostRepository extends JpaRepository<Host, Long> {
public Host findOneByNameIgnoreCase(String name);
}
HostSetRepository
package com.myproject.testJpa.entity.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.myproject.testJpa.entity.HostSet;
#Repository
public interface HostSetRepository extends JpaRepository<HostSet, Long> {
public HostSet findOneByNameIgnoreCase(String name);
}
When I run the application, it throws the following error when looping over the hosts of the retrieved hostSet in the fetch() method.
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.myproject.testJpa.entity.HostSet.hosts, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:188)
at com.myproject.testJpa.TestJpaApplication.fetch(TestJpaApplication.java:58)
at com.myproject.testJpa.TestJpaApplication.lambda$demo$0(TestJpaApplication.java:34)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784)
I've tried adding the #Transactional annotation in several places but to no avail. It's driving me crazy because I don't see what I'm doing wrong.
Thanks for your help!
It turns out that the #Transactional was not working in the TestJpaApplication class (I did not set it on the anonymous method, don't know how or if it's possible).
I moved the content to a separate service and it worked.
I'm facing some problem with displaying COUNT of a variable while querying a MySQL database. I have made a variable with annotation #Transient so that it's not included in the DB. But, I'm getting error while posting data in the same table in the DB, since while posting, there is no field count, count is only used to get COUNT(u_type). Is there any way with which I can display COUNT of a variable when I do a GET call (using SQL query) and no need to post it. TIA.
Class:
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.data.annotation.Transient;
#Entity // This tells Hibernate to make a table out of this class
public class UserClickData {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private String u_search_term;
private String u_sysid;
private String u_type;
#Transient
private long count;
public UserClickData(String u_type, long Count) { //, long count
this.u_type = u_type;
this.count=count;
}
public long getCount() {
return count;
}
public void setCount(long count) {
this.count=count;
}
public int getSys_id() {
return sys_id;
}
public void setSys_id(int sys_id) {
this.sys_id = sys_id;
}
public String getU_search_term() {
return u_search_term;
}
public void setU_search_term(String u_search_term) {
this.u_search_term = u_search_term;
}
public String getU_type() {
return u_type;
}
public void setU_type(String u_type) {
this.u_type = u_type;
}
}
Projection:
public interface UserClickProjection {
String getU_type();
long getCount();
}
DAO Code:
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import com.abc.datacollection.entity.UserClickData;
import com.abc.datacollection.entity.UserClickProjection;
import com.abc.datacollection.entity.UserProjection;
public interface UserClickDataRepository extends CrudRepository<UserClickData, Integer> {
public static final String FIND_QUERY =
"select new com.abc.datacollection.entity.UserClickData(user.u_type, COUNT(u_type)) from UserClickData user GROUP BY user.u_type ORDER BY COUNT(user.u_type) DESC";
#Query(value = FIND_QUERY)
//public List<UserProjection> getAllRequestResponseRecords();
List<UserClickProjection> findAllProjectedBy();
}
Controller:
#CrossOrigin(origins = "*")
#GetMapping(path="/all")
public #ResponseBody List<UserClickProjection> getAllUserClickDataRecords() {
return userClickDataRepository.findAllProjectedBy();
}
Import javax.persistence.Transient instead of org.springframework.data.annotation.Transient
Today I did some experiments with hibernate. Unfortunately it seems if I’m misunderstanding something about the sessions.
I have three entities (book “buch”, user “benutzer” and rent “leihstellung”).
Each book knows about the rents, it’s concerned by. Each rent knows about the associated book. Furthermore each rent knows about the fitting user and of course each user knows the associated rents.
I explicitly want to have this two way mappings.
Now I wrote a small tester which inserts some data. The insert progress works as expected. After inserting some data I would like to delete a user.
If I do this before the commit, hibernate gives me an error, because the user will be reinserted be the rents it belongs to (that even happens, if I manually delete the user from this rents). Here I don’t really understand why that happens.
Everything works fine, if I do a session.close and open a new session for deleting the user.
I guess, that there is a smarter way to do this within one session. But unfortunately I don’t know how this can be done.
Any explanation is welcome.
public class Worker implements Iworker{
private Sessiongetter sg;
private MainMenu mm;
public void work(File datei)
{
sg = new Sessiongetter();
Session session = sg.getSesseion();
WlBuchart wlBuchart = new WlBuchart(1, "Sachbuch");
Buch buch = new Buch("test", "ich", 1);
buch.setWlBuchart(wlBuchart);
Buch buch2 = new Buch("versuch", "du",2);
buch2.setWlBuchart(wlBuchart);
session.beginTransaction();
session.save(wlBuchart);
session.save(buch);
session.save(buch2);
Benutzer benutzer = new Benutzer("hans", "dampf", "Lehrer", "versuch");
session.save(benutzer);
Leihstellung leihstellung = new Leihstellung(benutzer, buch);
Leihstellung leihstellung2 = new Leihstellung(benutzer, buch2);
session.save(leihstellung);
session.save(leihstellung2);
benutzer.addLeihstellung(leihstellung);
benutzer.addLeihstellung(leihstellung2);
session.update(benutzer);
buch.addLeihstellung(leihstellung);
buch2.addLeihstellung(leihstellung2);
session.update(buch);
session.update(buch2);
session.remove(benutzer);
session.flush();
session.getTransaction().commit();
session.close();
System.out.println("fertig");
}
package code.logik;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.Session;
#Entity
#Table(name="benutzer")
public class Benutzer {
#Column(nullable=false)
private String vorname, nachname, gruppe;
#Id
private String kennung;
private boolean admin;
#Column(nullable=true)
private String kennwort;
#OneToMany(cascade=CascadeType.ALL, mappedBy="benutzer")
private List<Leihstellung>leihstellungs;
public String getKennwort() {
return kennwort;
}
public void setKennwort(String kennwort) {
this.kennwort = kennwort;
}
public Benutzer(String vorname, String nachname, String gruppe, String kennung) {
this.vorname=vorname;
this.nachname=nachname;
this.gruppe=gruppe;
this.kennung=kennung;
this.leihstellungs= new ArrayList<>();
}
public Benutzer() {
// TODO Auto-generated constructor stub
}
public String getVorname() {
return vorname;
}
public String getNachname() {
return nachname;
}
public String getGruppe() {
return gruppe;
}
public String getKennung() {
return kennung;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
public List<Leihstellung> getLeihstellungs() {
return leihstellungs;
}
public void addLeihstellung(Leihstellung leihstellung)
{
leihstellungs.add(leihstellung);
}
public int compare(Benutzer other)
{
if (this.getNachname().compareTo(other.getNachname())!=0)
{
return this.getNachname().compareTo(other.getNachname());
}
return this.getVorname().compareTo(other.getVorname());
}
}
package code.logik;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.ManyToAny;
#Entity
#Table(name="buch")
public class Buch {
#Column(nullable=false)
private String titel;
private String autor;
#ManyToOne
private WlBuchart wlBuchart;
#OneToMany(cascade=CascadeType.ALL, mappedBy="buch")
private List<Leihstellung>leihstellungs;
public WlBuchart getWlBuchart() {
return wlBuchart;
}
public void setWlBuchart(WlBuchart wlBuchart) {
this.wlBuchart = wlBuchart;
}
#Id
private int nummer;
public Buch(String titel, String autor,int nummer) {
this.titel=titel;
this.autor=autor;
this.nummer=nummer;
leihstellungs = new ArrayList<>();
}
public Buch() {
// TODO Auto-generated constructor stub
}
public String getTitel() {
return titel;
}
public String getAutor() {
return autor;
}
public int getNummer() {
return nummer;
}
public List<Leihstellung> getLeihstellungs() {
return leihstellungs;
}
public void addLeihstellung(Leihstellung leihstellung)
{
leihstellungs.add(leihstellung);
}
}
package code.logik;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="leihstellung")
public class Leihstellung {
#ManyToOne
private Benutzer benutzer;
#Id #GeneratedValue
private int id;
#Column(nullable=false)
private LocalDate von;
private LocalDate bis;
#ManyToOne
private Buch buch;
public Leihstellung(Benutzer benutzer, Buch buch) {
this.benutzer=benutzer;
this.buch=buch;
this.von = LocalDate.now();
}
public Leihstellung() {
// TODO Auto-generated constructor stub
}
public void setAbgegeben()
{
bis = LocalDate.now();
}
public Benutzer getBenutzer() {
return benutzer;
}
public int getId() {
return id;
}
public LocalDate getVon() {
return von;
}
public LocalDate getBis() {
return bis;
}
public Buch getBuch() {
return buch;
}
}
Found the solution myself. I had to delete the references from the connected rents and books.
Now everything works find.
My entity class is as follows
package com.ibs.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name = "InitialMedicalCheckUpG3")
public class InitialMedicalCheckUpEntity {
private int imcsId;
private String empId, status, updatedBy, remarks;
Date updatedOn;
#Column(name = "IMCS_ID")
public int getImcsId() {
return imcsId;
}
public void setImcsId(int imcsId) {
this.imcsId = imcsId;
}
#Id
#Column(name = "EMP_ID")
#GeneratedValue(generator = "increment", strategy = GenerationType.AUTO)
#GenericGenerator(name = "increment", strategy = "increment")
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
#Column(name = "STATUS")
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Column(name = "UPDATED_BY")
public String getUpdatedBy() {
return updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
#Column(name = "REMARKS")
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "UPDATED_ON", insertable = false)
public Date getUpdatedOn() {
return updatedOn;
}
public void setUpdatedOn(Date updatedOn) {
this.updatedOn = updatedOn;
}
}
Data access object ->
package com.ibs.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.ibs.entity.InitialMedicalCheckUpEntity;
#Repository
public class InitialMedicalCheckUpDaoImpl implements InitialMedicalCheckUpDao {
#Autowired
SessionFactory sessionFactory;
#Override
public List<InitialMedicalCheckUpEntity> getConfirmedList() {
// TODO Auto-generated method stub
return null;
}
#Override
public List<InitialMedicalCheckUpEntity> getNonConfirmedList() {
// TODO Auto-generated method stub
return null;
}
#Override
public void update(InitialMedicalCheckUpEntity e) {
// TODO Auto-generated method stub
System.out.println(e.getStatus());
sessionFactory.getCurrentSession().update(e);
}
}
Hibernate prepared the following query for my update statement->
Hibernate:
update InitialMedicalCheckUpG3 set IMCS_ID=?, REMARKS=?,STATUS=?,UPDATED_BY=?, UPDATED_ON=? where EMP_ID=?
So the table is not getting updated.
I use Dao from a service class->
package com.ibs.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ibs.dao.InitialMedicalCheckUpDao;
import com.ibs.entity.InitialMedicalCheckUpEntity;
#Service
public class InitialMedicalCheckUpServiceImpl implements
InitialMedicalCheckUpService {
#Autowired
InitialMedicalCheckUpDao dao;
#Override
public List<InitialMedicalCheckUpEntity> getConfirmedList() {
// TODO Auto-generated method stub
return null;
}
#Override
public List<InitialMedicalCheckUpEntity> getNonConfirmedList() {
// TODO Auto-generated method stub
return null;
}
#Override
#Transactional
public void update(InitialMedicalCheckUpEntity e) {
// TODO Auto-generated method stub
dao.update(e);
}
}
Every operation through hibernate needs to be associated with a transaction. You need to make sure that your update operation is a part of a transaction and this unit of work is committed. Make sure that you are associating this operation with a transaction and commit it.
Use the #Transactional annotation before the InitialMedicalCheckUpDaoImpl class, or before every method. Spring will then automatically add transactional characteristics for all methods within this class. This has the disadvantage when you would like to have transactions that can do more than one dao action.
A better design would be to have another class (a service) that calls the methods defined in the dao. This class can then be annotated with the #Transactional. This will result in better transaction definition because some transactions can then span more than one database operation, like insert then update.
EDIT
I just noticed that you have not overriden the equals and hashcode methods in your entity class. These are needed by hibernate to know if the entity is already in the database before updating, if the entity was detached from the session at some point or is used in a set. You can use the id field for this.
#Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null) {
return false;
}
if (!(o instanceof InitialMedicalCheckUpEntity)) {
return false;
}
return this.getEmpId()==o.getEmpId();
}
#Override
public int hashCode() {
return empId;
}
You may want to take a look at this Question
I am using Jboss7.1 and jpa , ejb
I want to insert data -with OneToMany relationship- into my mysql database.
I have two entitys personne and voiture. I want to save a person in my database and associate voiture for him. The problem is that when i test my code (test), i find that there is a new personne added to my database and there is no voiture added in the table voiture
please can you help me .
code :
the entity personne
package com.domain;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Set;
/**
* The persistent class for the personne database table.
*
*/
#Entity
public class Personne implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int idpersonne;
private String nom;
//bi-directional many-to-one association to Voiture
#OneToMany(mappedBy="personne")
private Set<Voiture> voitures;
public Personne() {
}
public Personne(String nom) {
super();
this.nom = nom;
}
public int getIdpersonne() {
return this.idpersonne;
}
public void setIdpersonne(int idpersonne) {
this.idpersonne = idpersonne;
}
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public Set<Voiture> getVoitures() {
return this.voitures;
}
public void setVoitures(Set<Voiture> voitures) {
this.voitures = voitures;
}
}
entity voiture
package com.domain;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the voiture database table.
*
*/
#Entity
public class Voiture implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int idvoiture;
private String type;
//bi-directional many-to-one association to Personne
#ManyToOne
private Personne personne;
public Voiture() {
}
public Voiture(String type) {
super();
this.type = type;
}
public int getIdvoiture() {
return this.idvoiture;
}
public void setIdvoiture(int idvoiture) {
this.idvoiture = idvoiture;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public Personne getPersonne() {
return this.personne;
}
public void setPersonne(Personne personne) {
this.personne = personne;
}
}
this is the interface
package com.DAO;
import javax.ejb.Remote;
import com.domain.Personne;
#Remote
public interface PersonneDAO {
public void save(Personne personne);
public String sayhello();
}
the implementation
package com.DAO.Impl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.DAO.VoitureDAO;
import com.domain.Voiture;
#Stateless
public class VoitureDAOImpl implements VoitureDAO {
#PersistenceContext(name = "JPADD")
EntityManager em;
#Override
public void save(Voiture voiture) {
em.persist(voiture);
}
}
the implementation
package com.DAO.Impl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.DAO.PersonneDAO;
import com.domain.Personne;
#Stateless
public class PersonneDAOImpl implements PersonneDAO {
#PersistenceContext(name = "JPADD")
EntityManager em;
#Override
public String sayhello() {
// TODO Auto-generated method stub
return "helllllllllllllllllo";
}
#Override
public void save(Personne personne) {
em.persist(personne);
}
}
this is the test
package test;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.DAO.PersonneDAO;
import com.domain.Personne;
import com.domain.Voiture;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
Context intialcontext;
Properties properties = new Properties();
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
try {
intialcontext = new InitialContext(properties);
PersonneDAO dao = (PersonneDAO) intialcontext
.lookup("ejb:/projetweb/PersonneDAOImpl!com.DAO.PersonneDAO");
// /----------------------------objet voiture-------------
Voiture voiture = new Voiture("216");
Set<Voiture> voitures = new HashSet<Voiture>();
voitures.add(voiture);
// -------------------------------------------------------
Personne personne = new Personne("slatnia");
personne.setVoitures(voitures);
dao.save(personne);
} catch (NamingException e) {
e.printStackTrace();
}
}
}
and this is my jboss-ejb-client.properties
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Try add following attributes to the #OneToMany annotation
#OneToMany(cascade=CascadeType.ALL)
You should add cascade = CascadeType.PERSIST in the #OneToMany
CascadeType.PERSIST
When persisting an entity, also persist the entities held in this
field. We suggest liberal application of this cascade rule, because if
the EntityManager finds a field that references a new entity during
flush, and the field does not use CascadeType.PERSIST, it is an error.
example:
#OneToMany(cascade = CascadeType.PERSIST)
private Set<Voiture> voitures;
Javadoc for CascadeType and other doc at here.