I'm trying to persist an entity that has a composite primary key but I get error :
12:59:48,221 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-56) SQL Error: 1110, SQLState: 42000
12:59:48,221 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-56) Column 'SENDERID' specified twice
I'm using EntityManager so I'm not sure where the 'SENDERID' is speciefied twice?
This is all the relevant classes:
Webservice:
#Path("friendservice")
public class FriendWebService {
#EJB
private FriendrequestFacade friendRequestFacade;
#GET
#Path("friendrequest")
#Produces(MediaType.TEXT_PLAIN)
public String insertFriendRequest(
#Context HttpServletRequest request){
String result = "false";
User user = (User) request.getSession().getAttribute("user");
User otherUser = (User) request.getSession().getAttribute("profileuser");
if((user != null) && (otherUser != null)){
if(user.getId() != otherUser.getId()){
System.out.println("Both users are alive.");
if(friendRequestFacade.insertFriendRequest(user, otherUser))
result = "true";
}
}
return result;
}
}
Facade:
#Stateless
public class FriendrequestFacade extends AbstractFacade<Friendrequest> {
#PersistenceContext(unitName = "FakebookPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public FriendrequestFacade() {
super(Friendrequest.class);
}
public boolean insertFriendRequest(User user, User otherUser){
Friendrequest fr = new Friendrequest();
FriendrequestPK frPK = new FriendrequestPK();
frPK.setSenderid(user.getId());
frPK.setReceiverid(otherUser.getId());
fr.setId(frPK);
em.clear();
em.persist(fr);
return true;
}
}
Entity:
#Entity
#XmlRootElement
#Table(name="FRIENDREQUEST")
#NamedQuery(name="Friendrequest.findAll", query="SELECT f FROM Friendrequest f")
public class Friendrequest implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private FriendrequestPK id;
#Temporal(TemporalType.TIMESTAMP)
private Date senddate;
//bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name="SENDERID")
private User user1;
//bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name="RECEIVERID")
private User user2;
public Friendrequest() {}
public FriendrequestPK getId() {
return this.id;
}
public void setId(FriendrequestPK id) {
this.id = id;
}
public Date getSenddate() {
return this.senddate;
}
public void setSenddate(Date senddate) {
this.senddate = senddate;
}
public User getUser1() {
return this.user1;
}
public void setUser1(User user1) {
this.user1 = user1;
}
public User getUser2() {
return this.user2;
}
public void setUser2(User user2) {
this.user2 = user2;
}
}
Composite Key:
#Embeddable
public class FriendrequestPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(insertable=false, updatable=false)
private int senderid;
#Column(insertable=false, updatable=false)
private int receiverid;
public FriendrequestPK() {}
public FriendrequestPK(int senderid, int receiverid){
this.senderid = senderid;
this.receiverid = receiverid;
}
public int getSenderid() {
return this.senderid;
}
public void setSenderid(int senderid) {
this.senderid = senderid;
}
public int getReceiverid() {
return this.receiverid;
}
public void setReceiverid(int receiverid) {
this.receiverid = receiverid;
}
}
What am I doing wrong?
First of all please let me clarify that I rarely use #EmbeddedId so I could be missing something. That being told, the error is telling you that SENDERID column is specified twice: first time in your entity and then in the composite key. The same is probably happening with RECEIVERID too.
Entity
public class Friendrequest implements Serializable {
...
#EmbeddedId
private FriendrequestPK id;
#ManyToOne
#JoinColumn(name="SENDERID") // Column = SENDERID
private User user1;
#ManyToOne
#JoinColumn(name="RECEIVERID") // Column = RECEIVERID
private User user2;
...
}
Composite key
public class FriendrequestPK implements Serializable {
...
#Column(insertable=false, updatable=false)
private int senderid; // Column = SENDERID
#Column(insertable=false, updatable=false)
private int receiverid; // Column = RECEIVERID
...
}
According to Mapping identifier properties section in Hibernate Annotations reference guide, the entity mapping should be done using #MapsId annotation:
public class Friendrequest implements Serializable {
...
#EmbeddedId
private FriendrequestPK id;
#MapsId("senderid") // senderid = Field in FriendrequestPK class
#ManyToOne
private User user1;
#MapsId("receiverid") // receiverid = Field in FriendrequestPK class
#ManyToOne
private User user2;
...
}
Related
I have a request table related to 2 tables where I save the request number according to the type of request that can be a request for water analysis and request for soil analysis, but when I try to delete or update the request table I get the error
Cannot delete or update a parent row: a foreign key constraint fails
My code that implements the relationships is the following is the following
//class for request
#Entity
#Table(name = "solicitud")
public class Solicitud implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
//#Column(unique=true)
//private String codigo;
#ManyToOne(fetch = FetchType.LAZY)
private Estado estado;
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
#NotNull
#Column(name="fecha")
private Date fecha;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
private Usuario usuario;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
private Usuario teclab;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
private TipoMuestra tmuestra;
//#Min(value = 0L, message = "Debe ingresar un valor positivo")
//#Pattern(regexp = "[\\s]*[0-9]*[1-9]+",message="msg")
#NotNull
private Integer numMuestras;
int year = 0;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Estado getEstado() {
return estado;
}
public void setEstado(Estado estado) {
this.estado = estado;
}
public Date getFecha() {
return fecha;
}
public void setFecha(Date fecha) {
this.fecha = fecha;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public TipoMuestra getTmuestra() {
return tmuestra;
}
public void setTmuestra(TipoMuestra tmuestra) {
this.tmuestra = tmuestra;
}
public Integer getNumMuestras() {
return numMuestras;
}
public void setNumMuestras(Integer numMuestras) {
this.numMuestras = numMuestras;
}
public Usuario getTeclab() {
return teclab;
}
public void setTeclab(Usuario teclab) {
this.teclab = teclab;
}
/*#PostPersist
public void generateCode() {
CodigoAgua agua=new CodigoAgua();
agua.setSolicitud(this);
agua.generateCode();
}*/
/**
*
*/
private static final long serialVersionUID = 1L;
}
//class for save number for type request water analysis
#Entity
#Table(name = "cagua")
public class CodigoAgua implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique=true)
private String codigo;
#OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name="solicitud_id")
private Solicitud solicitud;
int year = 0;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public Solicitud getSolicitud() {
return solicitud;
}
public void setSolicitud(Solicitud solicitud) {
this.solicitud = solicitud;
}
#PostPersist
public void generateCode() {
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
year = localDate.getYear();
this.codigo=year +" - "+id+" - A";
System.out.println("Codigo solicitud creado"+id+this.getSolicitud().getId());
}
/**
*
*/
private static final long serialVersionUID = 1L;
}
//class for save number for type request soil analysis
#Entity
#Table(name = "csuelo")
public class CodigoSuelo implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique=true)
private String codigo;
#OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name="solicitud_id")
private Solicitud solicitud;
int year = 0;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public Solicitud getSolicitud() {
return solicitud;
}
public void setSolicitud(Solicitud solicitud) {
this.solicitud = solicitud;
}
#PostPersist
public void generateCode() {
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
year = localDate.getYear();
this.codigo=year +" - "+id+" - S";
System.out.println("Codigo solicitud creado"+id+this.getSolicitud().getId());
}
/**
*
*/
private static final long serialVersionUID = 1L;
}
This message indicates that you want to delete a row from table1, while its primary key is present as a foreign key in table2.
To delete a record from table1, you must delete all the lines that refer to it in the other tables in order to be able to delete this record.
I hope I've helped you
I am not able to fetch all records from two tables using the below query
I have tried this but I am getting a result from one table only. I want a result of both the tables i.e, client_software_param_mapping and client_file_configuration having the same ClientId which is a foreign key from third pojo(client_software_configuration) to first and second pojo.
public Result showClientConfiguration() {EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("defaultPU");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query q=entityManager.
createQuery("SELECT c FROM client_software_param_mapping c JOIN fetch client_file_configuration f ON c.ClientId=f.ClientId");
List data =q.getResultList();
return ok(Json.toJson(data));
}
first pojo
#Entity
public class client_file_configuration {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String sourceFolder;
private String sourceFile;
private String processingFolder;
private String processingFile;
private String processedFolder;
private int intervalInMin;
private String readAfterDelay;
private String parserClass;
private String directoryMode;
private String fileMode;
private String actionMode;
private String type;
private String fileExpressionResolver;
#OneToOne
#JoinColumn(name = "ClientId")
private client_software_configuration clientSoftwareConfiguration;
public client_software_configuration getClientSoftwareConfiguration() {
return clientSoftwareConfiguration;
}
public void setClientSoftwareConfiguration(client_software_configuration clientSoftwareConfiguration) {
this.clientSoftwareConfiguration = clientSoftwareConfiguration;
}
}
secondpojo
#Entity
public class client_software_param_mapping {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String paramKey;
private String paramValue;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getParamKey() {
return paramKey;
}
public void setParamKey(String paramKey) {
this.paramKey = paramKey;
}
public String getParamValue() {
return paramValue;
}
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}
#ManyToOne
#JoinColumn(name = "ClientId")
private client_software_configuration clientSoftwareConfiguration;
public client_software_configuration getClientSoftwareConfiguration() {
return clientSoftwareConfiguration;
}
public void setClientSoftwareConfiguration(client_software_configuration clientSoftwareConfiguration) {
this.clientSoftwareConfiguration = clientSoftwareConfiguration;
}
}
thirdpojo
#Entity
public class client_software_configuration {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String url;
private int port;
private String endPoint;
private String isPost;
private String isPing;
private String params;
private int serialNo;
private String dateFormat;
private String token;
}
this is the right query as it is returning the object of the third pojo present at that ClientId so it is able to understand the type of ClientId.JPQL never uses table and column names. It always uses entity names and their mapped fields/properties names.so here I have taken the object of the third pojo having the ClientId field.
select c,p from client_file_configuration c,client_software_param_mapping p where c.clientSoftwareConfiguration = p.clientSoftwareConfiguration
I'm trying implement a rest service. I have created my entitys and daos, and when use this everthyng works fine.
But when I trye expose the information in rest json, the infinite recursion error occur.
I have read many topic about this error, but not is so clear for me.
I'm have tried so many alternatives that is hard talk about each.
When I debug my code, I see that the data from dao is correctly, the problem occur when I trie use json. Whe I use jsf page works fine.
I have tried use Gson and return String in my rest method, but stackoverflow error occur to.
Bellow I post my implememtation (all), because a dont have idea about the problem.
I using wildfly server...
Thanks in advance
Model's
#Entity
#Table(name="usertable")
#NamedQuery(name="UserModel.findAll", query="SELECT u FROM UserModel u")
#XmlRootElement
public class UserModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String USId;
#Temporal(TemporalType.DATE)
#Column(nullable=false)
private Date userNascimento;
#Column(nullable=false, length=45)
private String USMail;
#Column(nullable=false, length=150)
private String USName;
#Column(nullable=false, length=45)
private String USNick;
#Column(nullable=false, length=45)
private String USPassword;
//bi-directional many-to-one association to UserAddressModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="usertable")
private List<UserAddressModel> listAddressModel;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="usertable")
private List<UserFoneModel> listFoneModel;
public UserModel() {
}
public String getUSId() {
return this.USId;
}
public void setUSId(String USId) {
this.USId = USId;
}
public Date getUserNascimento() {
return this.userNascimento;
}
public void setUserNascimento(Date userNascimento) {
this.userNascimento = userNascimento;
}
public String getUSMail() {
return this.USMail;
}
public void setUSMail(String USMail) {
this.USMail = USMail;
}
public String getUSName() {
return this.USName;
}
public void setUSName(String USName) {
this.USName = USName;
}
public String getUSNick() {
return this.USNick;
}
public void setUSNick(String USNick) {
this.USNick = USNick;
}
public String getUSPassword() {
return this.USPassword;
}
public void setUSPassword(String USPassword) {
this.USPassword = USPassword;
}
public List<UserAddressModel> getUseraddresstables() {
return this.listAddressModel;
}
public void setUseraddresstables(List<UserAddressModel> useraddresstables) {
this.listAddressModel = useraddresstables;
}
public UserAddressModel addUseraddresstable(UserAddressModel useraddresstable) {
getUseraddresstables().add(useraddresstable);
useraddresstable.setUsertable(this);
return useraddresstable;
}
public UserAddressModel removeUseraddresstable(UserAddressModel useraddresstable) {
getUseraddresstables().remove(useraddresstable);
useraddresstable.setUsertable(null);
return useraddresstable;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setUsertable(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setUsertable(null);
return userfonetable;
}
}
#Entity
#Table(name="userfonetable")
#NamedQuery(name="UserFoneModel.findAll", query="SELECT u FROM UserFoneModel u")
public class UserFoneModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String UFId;
#Column(nullable=false)
private short UFDdd;
#Column(nullable=false)
private int UFFone;
//bi-directional many-to-one association to UserModel
#ManyToOne
#JoinColumn(name="UFUserID", nullable=false)
private UserModel usertable;
//bi-directional many-to-one association to OperadorasModel
#ManyToOne
#JoinColumn(name="UFOperadoraID", nullable=false)
private OperadorasModel operadorastable;
//bi-directional many-to-one association to TiposFoneModel
#ManyToOne
#JoinColumn(name="UFTipoTelefone", nullable=false)
private TiposFoneModel tbTipostelefone;
public UserFoneModel() {
}
public String getUFId() {
return this.UFId;
}
public void setUFId(String UFId) {
this.UFId = UFId;
}
public short getUFDdd() {
return this.UFDdd;
}
public void setUFDdd(short UFDdd) {
this.UFDdd = UFDdd;
}
public int getUFFone() {
return this.UFFone;
}
public void setUFFone(int UFFone) {
this.UFFone = UFFone;
}
public UserModel getUsertable() {
return this.usertable;
}
public void setUsertable(UserModel usertable) {
this.usertable = usertable;
}
public OperadorasModel getOperadorastable() {
return this.operadorastable;
}
public void setOperadorastable(OperadorasModel operadorastable) {
this.operadorastable = operadorastable;
}
public TiposFoneModel getTbTipostelefone() {
return this.tbTipostelefone;
}
public void setTbTipostelefone(TiposFoneModel tbTipostelefone) {
this.tbTipostelefone = tbTipostelefone;
}
}
#Entity
#Table(name="useraddresstable")
#NamedQuery(name="UserAddressModel.findAll", query="SELECT u FROM UserAddressModel u")
public class UserAddressModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private String UAId;
#Column(nullable=false, length=100)
private String UABairro;
#Column(nullable=false, length=100)
private String UACidade;
#Column(length=45)
private String UAComplemento;
#Column(nullable=false, length=2)
private String UAEstado;
#Column(nullable=false)
private int UANumero;
#Column(length=100)
private String UARua;
//bi-directional many-to-one association to UserModel
#ManyToOne
#JoinColumn(name="UAUserID", nullable=false)
private UserModel usertable;
public UserAddressModel() {
}
public String getUAId() {
return this.UAId;
}
public void setUAId(String UAId) {
this.UAId = UAId;
}
public String getUABairro() {
return this.UABairro;
}
public void setUABairro(String UABairro) {
this.UABairro = UABairro;
}
public String getUACidade() {
return this.UACidade;
}
public void setUACidade(String UACidade) {
this.UACidade = UACidade;
}
public String getUAComplemento() {
return this.UAComplemento;
}
public void setUAComplemento(String UAComplemento) {
this.UAComplemento = UAComplemento;
}
public String getUAEstado() {
return this.UAEstado;
}
public void setUAEstado(String UAEstado) {
this.UAEstado = UAEstado;
}
public int getUANumero() {
return this.UANumero;
}
public void setUANumero(int UANumero) {
this.UANumero = UANumero;
}
public String getUARua() {
return this.UARua;
}
public void setUARua(String UARua) {
this.UARua = UARua;
}
public UserModel getUsertable() {
return this.usertable;
}
public void setUsertable(UserModel usertable) {
this.usertable = usertable;
}
}
#Entity
#Table(name="tb_tipostelefone")
#NamedQuery(name="TiposFoneModel.findAll", query="SELECT t FROM TiposFoneModel t")
public class TiposFoneModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private short TFId;
#Column(nullable=false, length=45)
private String TFDescricao;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="tbTipostelefone")
private List<UserFoneModel> listFoneModel;
public TiposFoneModel() {
}
public short getTFId() {
return this.TFId;
}
public void setTFId(short TFId) {
this.TFId = TFId;
}
public String getTFDescricao() {
return this.TFDescricao;
}
public void setTFDescricao(String TFDescricao) {
this.TFDescricao = TFDescricao;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setTbTipostelefone(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setTbTipostelefone(null);
return userfonetable;
}
}
#Entity
#Table(name="operadorastable")
#NamedQuery(name="OperadorasModel.findAll", query="SELECT o FROM OperadorasModel o")
public class OperadorasModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private short OPCodigo;
#Column(nullable=false, length=100)
private String opNome;
//bi-directional many-to-one association to UserFoneModel
#OneToMany(fetch = FetchType.EAGER, mappedBy="operadorastable")
private List<UserFoneModel> listFoneModel;
public OperadorasModel() {
}
public short getOPCodigo() {
return this.OPCodigo;
}
public void setOPCodigo(short OPCodigo) {
this.OPCodigo = OPCodigo;
}
public String getOpNome() {
return this.opNome;
}
public void setOpNome(String opNome) {
this.opNome = opNome;
}
public List<UserFoneModel> getUserfonetables() {
return this.listFoneModel;
}
public void setUserfonetables(List<UserFoneModel> userfonetables) {
this.listFoneModel = userfonetables;
}
public UserFoneModel addUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().add(userfonetable);
userfonetable.setOperadorastable(this);
return userfonetable;
}
public UserFoneModel removeUserfonetable(UserFoneModel userfonetable) {
getUserfonetables().remove(userfonetable);
userfonetable.setOperadorastable(null);
return userfonetable;
}
}
DAO
#Stateless
#LocalBean
public class UserDao {
/**
* Default constructor.
*/
#PersistenceContext
EntityManager em;
public UserDao() {
// TODO Auto-generated constructor stub
}
public List<UserModel> listAll()
{
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<UserModel> cq = cb.createQuery(UserModel.class);
Root<UserModel> rootEntry = cq.from(UserModel.class);
CriteriaQuery<UserModel> all = cq.select(rootEntry);
TypedQuery<UserModel> allQuery = em.createQuery(all);
List<UserModel> listU = allQuery.getResultList();
return listU;
/*
Query query = em.createQuery("SELECT u FROM UserModel u");
return query.getResultList();
*/
}
}
My Rest
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import br.com.avera.dao.UserDao;
import br.com.avera.model.UserAddressModel;
import br.com.avera.model.UserFoneModel;
import br.com.avera.model.UserModel;
#Path("/users")
public class UserRest {
#Inject
UserDao userDao;
#GET
#Produces(MediaType.APPLICATION_JSON)
public UserModel getUser()
{
List<UserModel> userModelList = userDao.listAll();
UserModel userModel = userModelList.get(0);
List<UserFoneModel> lFone = userModel.getUserfonetables();
for (UserFoneModel userFoneModel : lFone) {
System.out.println(userFoneModel.getUFDdd());
System.out.println(userFoneModel.getUFFone());
}
System.out.println("OOOOOO");
List<UserAddressModel> lAddressModels = userModel.getUseraddresstables();
for (UserAddressModel userAddressModel : lAddressModels) {
System.out.println(userAddressModel.getUACidade());
System.out.println(userAddressModel.getUAEstado());
}
return userModel;
}
}
i get an error when i try to get an item from my dbms. following error
com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.pharmawizardcabinet.core.entity.cabinet.Cabinet.listaFarmaci, could not initialize proxy - no Session (through reference chain: com.pharmawizardcabinet.web.beans.ResponseCabinet["cabinet"]->com.pharmawizardcabinet.core.entity.cabinet.Cabinet["listaFarmaci"])
this is my conteiner
#Entity
#Table(name = "Cabinet")
public class Cabinet implements Serializable {
private static final long serialVersionUID = 7311927404447970875L;
#Id
#Column(name = "Id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "cabinet")
private List<Farmaco> listaFarmaci;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "user")
private User user;
#Column(name = "timestamp")
#Temporal(TemporalType.DATE)
private Date setLastModified;
public Cabinet() {
}
#PostPersist
#PostUpdate
private void setLastUpdate() {
this.setLastModified = new Date();
}
public List<Farmaco> getListaFarmaci() {
return listaFarmaci;
}
public void setListaFarmaci(List<Farmaco> listaFarmaci) {
this.listaFarmaci = listaFarmaci;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public Date getSetLastModified() {
return setLastModified;
}
public void setSetLastModified(Date setLastModified) {
this.setLastModified = setLastModified;
}
}
and this is the item
#Entity
#Table(name = "Farmaco")
public class Farmaco implements Serializable {
private static final long serialVersionUID = -152536676742398255L;
public Farmaco() {
// TODO Auto-generated constructor stub
}
#Column(name = "nome_farmaco")
private String nome;
#Column(name = "codice")
private String codice;
#Column(name = "azienda")
private String azienda;
#Id
#Column(name = "Id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
#Column(name = "scadenza")
#Temporal(TemporalType.DATE)
private Date scadenza;
#Enumerated(EnumType.STRING)
#Column(name = "posologia")
private Posologia posologia;
#Column(name = "quantita")
private Integer quantita;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "note")
private Note note;
#ManyToOne(cascade =CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "cabinet_id")
private Cabinet cabinet;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCodice() {
return codice;
}
public void setCodice(String codice) {
this.codice = codice;
}
public String getAzienda() {
return azienda;
}
public void setAzienda(String azienda) {
this.azienda = azienda;
}
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public Date getScadenza() {
return scadenza;
}
public void setScadenza(Date scadenza) {
this.scadenza = scadenza;
}
public Posologia getPosologia() {
return posologia;
}
public void setPosologia(Posologia posologia) {
this.posologia = posologia;
}
public Integer getQuantita() {
return quantita;
}
public void setQuantita(Integer quantita) {
this.quantita = quantita;
}
public Note getNote() {
return note;
}
public void setNote(Note note) {
this.note = note;
}
public Cabinet getCabinet() {
return cabinet;
}
public void setCabinet(Cabinet cabinet) {
this.cabinet = cabinet;
}
}
controller is this
#Component("managerCabinet")
public class ManagerCabinet {
private static Logger logger = Logger.getLogger(ManagerCabinet.class);
#PersistenceContext(name = "pwcabinet-jpa")
private EntityManager entityManager;
#Transactional
public Cabinet getCabinetByUser(User user) {
logger.debug("[getCabinetByUser] user: " + user.getId());
return _getCabinetByUser(user);
}
private Cabinet _getCabinetByUser(User user) {
logger.debug("[_getCabinetByUser] user: " + user.getId());
User find = entityManager.find(User.class, user.getId());
Query searchCabinetByUser = entityManager.createQuery("Select c from Cabinet c where c.user = :userId", Cabinet.class);
searchCabinetByUser.setParameter("userId", find);
Cabinet cabinetSearch = (Cabinet) searchCabinetByUser.getSingleResult();
cabinetSearch.setUser(find);
return cabinetSearch;
}
}
but i continue to get error.
if i use the annotation #JsonIgnore in this way
#JsonIgnore
public List<Farmaco> getListaFarmaci() {
return listaFarmaci;
}
they works, but i need this information in my result. how i solve it?
When your method private Cabinet _getCabinetByUser(User user) returns the Cabinet instance is then in the 'detached' state, viz. is no longer associated with a persistence context.
When an item is in a detached state non-eagerly fetched associations can longer be accessed.
As the default fetch for #OneToMany is Lazy then in your case
#OneToMany(cascade = CascadeType.ALL, mappedBy = "cabinet")
private List<Farmaco> listaFarmaci;
the field listaFarmaci can no longer be accessed once the loaded Cabinet is detached from the persistence context.
You have various means of dealing with this which would include:
Marking the field as being eagerly fetched (not good as will always be eagerly fetched regardless of whether required or not).
Forcing the persistence context to remain open until all processing is done typically referred to as the OpenSessionInView pattern (or anti-pattern) depending on your point of view: http://java.dzone.com/articles/open-session-view-design
Ensuring all data required for use case is initialized before detachment. There are various ways of achieving this:
Simply accessing the collection is some way e.g. by calling size() but this may not work with all JPA providers.
Specifying FETCH JOIN in your JPQL query which loads the Cabinet (although this has side effects). http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Join_Fetching
I am modeling a database.
There is TRIPLE which contains three CONCEPT. So the primary key of the class TRIPLE is three uri all together. (One concept could be in different TRIPLE).
Also TRIPLE is related with another class, ANNOTATION, and here is the question, how can triple_id be identified?? But first of all, if building this Id composite is correct.
To model that:
Concept.java
#Entity
#Table(name = "concept")
public class Concept implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String id;
private List<TripleDBModel> triples;
#ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY,
mappedBy = "concepts"
)
public List<TripleDBModel> getTriples() {
return triples;
}
public void setTriples(List<TripleDBModel> triples) {
this.triples = triples;
}
ConceptPk.java
#Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String uri;
public ConceptPk(String uri, String label){
this.uri = uri;
}
public ConceptPk(){
super();
}
#Id
#Column(name = "uri", length = 100, unique = true, nullable = false)
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
}
Triple.java
#Entity
#IdClass(ConceptPk.class)
#Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
protected String conceptUriSubject;
protected String conceptUriObject;
protected String conceptUriPredicate;
#ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY
)
#JoinTable(name = "triple_has_concept",
joinColumns=#JoinColumn(name="uri"),
inverseJoinColumns=#JoinColumn(name="triple_id")) //What shoul I write here???
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
#Id public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
#Id public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
#Id public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
}
Thanks in advance!!
You could use an Id class like this:
class TripleId implements Serializable {
#Column(...)
private String conceptUriSubject;
#Column(...)
private String conceptUriObject;
}
And use it in Triple:
#Entity
#Table(name = "triple")
public class TripleDBModel {
#EmbeddedId
private TripleId id;
...
}
Also note that you can provide multiple join columns:
inverseJoinColumns= {#JoinColumn(name="subjectUri"), #JoinColumn(name="objectUri"), ... }