My situation is this: I am creating a marketplace where users can buy and sell products. I am trying to list a product with a ManyToOne relationship with the logged in user. I am getting the error: Field 'user_id' doesn't have a default value. Im guessing this is because I haven't set the user_id but I'm not sure how to.
Here is the code:
#Entity
#Table(name = "msItem")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long itemId;
#Column(nullable = false, length = 45)
private String itemName;
#Column(nullable = false)
private int itemPrice;
#Column(nullable = false, length = 100)
private String itemDesc;
#Column(nullable = false, length = 100)
private String category;
#Column(nullable = false, length = 100)
private String image;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false, insertable=false, updatable=false)
private User user;
public long getItemId() {
return itemId;
}
public void setItemId(long itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemPrice() {
return itemPrice;
}
public void setItemPrice(int itemPrice) {
this.itemPrice = itemPrice;
}
public String getItemDesc() {
return itemDesc;
}
public void setItemDesc(String itemDesc) {
this.itemDesc = itemDesc;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public User user() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
#Service
public class ItemServiceImp{
#Autowired
private ItemRepository itemRepository;
public List<Item> listItems(User user) {
return itemRepository.findByUser(user);
}
}
#Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
public List<Item> findByUser(User user);
}
#Controller
public class ProductController {
#Autowired
private ItemRepository itemRepository;
#GetMapping("/listItem")
public String listing(Model model) {
model.addAttribute("item", new Item());
return "addItem";
}
#PostMapping("/process_Item")
public String itemAdd(Item item) {
itemRepository.save(item);
return "home_page";
}
}
Error is happening at line 27 of controller class
Please help.. Thank you in advance!
There are a few ways to get a User connected to an Item. Since you are using the current logged in user, one way is to retrieve that user's User object information from the database and then attaching it to the Item you plan to save right before calling:
itemRepository.save(item).
As I don't know how you store session information I cannot give an exact way but as an example if you are using Spring Security you could use the following:
#PostMapping("/process_Item")
public String itemAdd(Item item, Principal principal) {
User user = userRepository.findByUsername(principal.getName());
item.setUser(user);
itemRepository.save(item);
return "home_page";
}
I have these entities
NormalizedChannelStock.java
#Entity
#Table(name = "stocks")
public class NormalizedChannelStock {
#EmbeddedId
private NormalizedChannelStockId id;
#Column(name = "qty")
private int qty;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "channel_id", insertable = false, updatable = false)
private Channel channel;
#Column(name = "created_at", updatable = false)
private Timestamp createdAt;
#Column(name = "updated_at", updatable = false)
private Timestamp updatedAt;
public NormalizedChannelStockId getId() {
return id;
}
public void setId(NormalizedChannelStockId id) {
this.id = id;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public Channel getChannel() {
return channel;
}
public void setChannel(Channel channel) {
this.channel = channel;
}
public Timestamp getCreatedAt() {
return createdAt;
}
public Timestamp getUpdatedAt() {
return updatedAt;
}
}
NormalizedChannelStockId.java
#Embeddable
public class NormalizedChannelStockId implements Serializable {
#Column(name = "channel_id")
private Integer channelId;
#Column(name = "sku")
private String sku;
public NormalizedChannelStockId() {
}
public NormalizedChannelStockId(Integer channelId, String sku) {
this.channelId = channelId;
this.sku = sku;
}
public Integer getChannelId() {
return channelId;
}
public void setChannelId(Integer channelId) {
this.channelId = channelId;
}
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NormalizedChannelStockId that = (NormalizedChannelStockId) o;
return channelId.equals(that.channelId) &&
sku.equals(that.sku);
}
#Override
public int hashCode() {
return Objects.hash(channelId, sku);
}
}
Channel.java
#Entity
#Table(name = "channels")
public class Channel {
#Id
#Column(name = "channel_id")
private int channelId;
#Column(name = "channel_name")
private String channelName;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "store_id", insertable = false, updatable = false)
private Store store;
public int getChannelId() {
return channelId;
}
public void setChannelId(int channelId) {
this.channelId = channelId;
}
public String getChannelName() {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
}
The problem I'm facing is when I call
List<NormalizedChannelStock> entitiesToSave = ...
List<NormalizedChannelStock> savedEntities = normalizedChannelStockService.saveAll(entitiesToSave);
The returned entities in savedEntities have their Channel inner objects set to null, as well as their created_at and updated_at as shown
Is this normal behaviour? When I run a findAllById on the Repository, the Channels inside the Entities are loaded lazily properly, so I believe the entities are properly mapped in code. The problem is after I save them.
Does JPA not reload the entity after saving it?
As you stated in the comments you did not set those values before saving.
JPA does not load them for you. JPA pretty much doesn't load anything upon saving except the id if it is generated by the database.
A more common case of the same problem/limitation/misconceptions are bidirectional relationships: JPA pretty much ignores the not owning side and the developer has to make sure that both sides are in sync at all times.
You would have to refresh the entity yourself. Note that just loading it in the same transaction would have no effect because it would come from the 1st level cache and would be exactly the same instance.
public User updateUser(User user) {
try {
User result = session.get(User.class, user.getId());
if (result == null) {
throw new FilamentNoSuchRecordException(new CoreError(304, "User does not exist"));
}
session.clear();
session.update(user);
return user;
} catch (HibernateException e) {
e.printStackTrace();
}
throw new FilamentDataConnectivityException(new CoreError(305,"Connectivity issue. Please see System Administrator"));
}
customer model is as follows
#Entity
#Table(name = "customers")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
#DynamicUpdate(value=true)
#SelectBeforeUpdate(value=true)
#SQLDelete(sql="Update customers SET deleted = true where customer_id=?")
#Where(clause="deleted != true")
#ApiModel(description="Create or update Customers")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Customer {
#Id
#Column(name="customer_id")
#NotNull
#GeneratedValue(strategy=GenerationType.AUTO)
private int id = 0;
#Column(name="name")
#ApiModelProperty(value="The name of the customer", example="Mr J. Bond")
#NotNull
private String name;
#Column(name="description")
#ApiModelProperty(value="Desciption of the customer")
#NotNull
private String description;
#Column(name="logo_url")
#ApiModelProperty(value="Logo of user")
#NotNull
private String logo;
#Column(name="created_at")
#ApiModelProperty(value="The date the item was created", example="")
#NotNull
private Date createdAt;
#Column(name="updated_at")
#ApiModelProperty(value="The date the item was updated", example="")
#NotNull
private Date updatedAt;
#ApiModelProperty(hidden=true)
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Application> applications = new HashSet<Application>();
#ManyToMany(mappedBy = "customers")
private Set<Service> services = new HashSet<Service>();
#ApiModelProperty(hidden=true)
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<User> users = new HashSet<User>();
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(
name = "customer_subscription",
joinColumns = #JoinColumn(name = "customer_id"),
inverseJoinColumns = #JoinColumn(name = "subscription_id")
)
private Set<Subscription> subscriptions = new HashSet<Subscription>();
#ApiModelProperty(hidden=true)
#OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Corpus> corpus = new HashSet<Corpus>();
#Column(name="deleted")
#NotNull
private boolean deleteFlag;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Application> getApplications() {
return applications;
}
public void setApplications(Set<Application> applications) {
this.applications = applications;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public Set<Service> getServices() {
return services;
}
public void setServices(Set<Service> services) {
this.services = services;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Set<Corpus> getCorpus() {
return corpus;
}
public void setCorpus(Set<Corpus> corpus) {
this.corpus = corpus;
}
public Set<Subscription> getSubscriptions() {
return subscriptions;
}
public void setSubscriptions(Set<Subscription> subscriptions) {
this.subscriptions = subscriptions;
}
public boolean getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(boolean deleteFlag) {
this.deleteFlag = deleteFlag;
}
}
I check whether the object exists within the database, then update with an object, for example all fields could be null apart from the ID and the one thats needs to be updated. All fields are set to #NotNull in the model and I am using the #DynamicUpdate(value=true) and #SelectBeforeUpdate(value=true) annotations, but these seem to do nothing.
Just get failure saying the null fields can not be null. How do I update the row?
As we discussed in above comments, try this -
public User updateUser(User user) {
try {
User result = session.get(User.class, user.getId());
if (result == null) {
throw new FilamentNoSuchRecordException(new CoreError(304, "User does not exist"));
}
result.setName(user.getName()); // update some properties
session.update(result); // you should update 'result', not 'user'
return result;
} catch (HibernateException e) {
e.printStackTrace();
throw new FilamentDataConnectivityException(new CoreError(305,"Connectivity issue. Please see System Administrator"));
}
}
By using this method I found in another stack overflow post solved the issue. This checks each field and uses the 'not null' value. Then i can update from an object with only 1 field changed.
public static <T> T getNotNull(T a, T b) {
return b != null && a != null && !a.equals(b) ? a : b;
}
I have a criteria that looks like this:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.setFetchMode("role", FetchMode.JOIN)
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("formApprovals", "f")
.add(Restrictions. eq("f.latestApproval", true))
.list();
return result;
}
At first look it should be working, but no matter if I send true or false value in the parameter, the result will always be
[{
"roleIsActive": true,
"roleName": "role1",
"roleNotes": "note",
"formApprovals": [
{
"approvalNotes": "good",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 1,
"latestApproval": true
},
{
"approvalNotes": "bad",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 2,
"latestApproval": false
}
}]
As you can see, the "formApprovals" brings all registers in the database, even if I create the restriction for the latestApproval property
The property declaration in the parent object (role) is:
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
Checking the console, I can see that the where clause is being generated properly by hibernate, however, I can see that after that there are other queries, is it possible that those queries (I have no idea why are they there) are overwriting my criteria?
Any ideas?
EDIT
FormApproval Class
#Entity
#Table(name="FormApproval"
,catalog="catalog"
)
public class FormApproval implements java.io.Serializable {
private static final long serialVersionUID = 8L;
private int idformApproval;
private role role;
private Integer fkapprovedBy;
private Date approvedDate;
private String approvalNotes;
private boolean latestApproval;
public FormApproval() {
}
public FormApproval(int idformApproval, role role) {
this.idformApproval = idformApproval;
this.role = role;
}
public FormApproval(int idformApproval, role role, Integer fkapprovedBy, Date approvedDate, String approvalNotes, boolean latestApproval) {
this.idformApproval = idformApproval;
this.role = role;
this.fkapprovedBy = fkapprovedBy;
this.approvedDate = approvedDate;
this.approvalNotes = approvalNotes;
this.latestApproval = latestApproval;
}
#Id #GeneratedValue(strategy = IDENTITY)
#Column(name="IDFormApproval", unique=true, nullable=false)
public int getIdformApproval() {
return this.idformApproval;
}
public void setIdformApproval(int idformApproval) {
this.idformApproval = idformApproval;
}
#JsonIgnore
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="FKRole", nullable=false)
public role getrole() {
return this.role;
}
public void setrole(role role) {
this.role = role;
}
#Column(name="LatestApproval")
public boolean getLatestApproval() {
return this.latestApproval;
}
public void setLatestApproval(boolean latestApproval) {
this.latestApproval = latestApproval;
}
#Column(name="FKApprovedBy")
public Integer getFkapprovedBy() {
return this.fkapprovedBy;
}
public void setFkapprovedBy(Integer fkapprovedBy) {
this.fkapprovedBy = fkapprovedBy;
}
#Temporal(TemporalType.DATE)
#Column(name="ApprovedDate", length=10)
public Date getApprovedDate() {
return this.approvedDate;
}
public void setApprovedDate(Date approvedDate) {
this.approvedDate = approvedDate;
}
#Column(name="ApprovalNotes")
public String getApprovalNotes() {
return this.approvalNotes;
}
public void setApprovalNotes(String approvalNotes) {
this.approvalNotes = approvalNotes;
}
}
Role Class
#Entity
#Table(name="Role"
,catalog="catalog"
)
public class Role implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int idRole;
private WorkType workType;
private String roleName;
private String roleNotes;
private boolean roleIsActive;
private Set<FormApproval> formApprovals = new HashSet<FormApproval>(0);
private Set<Topicrole> topicRoles = new HashSet<TopicRole>(0);
private Set<FormFeedBack> formFeedBacks = new HashSet<FormFeedBack>(0);
private Set<UserRole> userRoles = new HashSet<UserRrole>(0);
private Set<Interview> interviews = new HashSet<Interview>(0);
public Role() {
}
public Role(int idRole, WorkType workType, String roleName, boolean roleIsActive) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleIsActive = roleIsActive;
}
public Role(int idRole, WorkType workType, String roleName, String roleNotes, boolean roleIsActive, Set<FormApproval> formApprovals, Set<TopicRole> topicRoles, Set<FormFeedBack> formFeedBacks, Set<UserRole> userRoles, Set<Interview> interviews) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleNotes = roleNotes;
this.roleIsActive = roleIsActive;
this.formApprovals = formApprovals;
this.topicRoles = topicRoles;
this.formFeedBacks = formFeedBacks;
this.userRoles = userRoles;
this.interviews = interviews;
}
#Id #GeneratedValue(strategy = IDENTITY)
#Column(name="IDRole", unique=true, nullable=false)
public int getIdrole() {
return this.idRole;
}
public void setIdrole(int idRole) {
this.idRole = idRole;
}
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="FKWorkType", nullable=false)
public WorkType getWorkType() {
return this.workType;
}
public void setWorkType(WorkType workType) {
this.workType = workType;
}
#Column(name="RoleName", nullable=false)
public String getRoleName() {
return this.roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
#Column(name="RoleNotes")
public String getRoleNotes() {
return this.roleNotes;
}
public void setRoleNotes(String roleNotes) {
this.roleNotes = roleNotes;
}
#Column(name="RoleIsActive", nullable=false)
public boolean isRoleIsActive() {
return this.roleIsActive;
}
public void setRoleIsActive(boolean roleIsActive) {
this.roleIsActive = roleIsActive;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<TopicRole> getTopicRoles() {
return this.topicRoles;
}
public void setTopicRoles(Set<TopicRole> topicRoles) {
this.topicRoles = topicRoles;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
#JsonManagedReference
public Set<FormFeedBack> getFormFeedBacks() {
return this.formFeedBacks;
}
public void setFormFeedBacks(Set<FormFeedBack> formFeedBacks) {
this.formFeedBacks = formFeedBacks;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<UserRole> getUserRoles() {
return this.userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="acnrole")
public Set<Interview> getInterviews() {
return this.interviews;
}
public void setInterviews(Set<Interview> interviews) {
this.interviews = interviews;
}
}
You might try using the restriction as part of ON clause on top of the association.
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
#Where(clause=" latestApproval='true' ")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
Also you can eliminate setting FetchMode.JOIN fetch by pointing to the association path using the method org.hibernate.Criteria.createAlias(String associationPath, String alias, JoinType joinType)
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(Role.class, "role")
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("role.formApprovals", "formApprovals", JoinType.LEFT_OUTER_JOIN);
return criteria.list();
}
Update:
For older versions of hibernate, use the other method below. Where joinType value would be 1 for LEFT_OUTER_JOIN and join clause can be passed as the 4th argument.
public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException;
Fixed using
.createCriteria("formApprovals","f",1,Restrictions.eq("f.latestApproval", status))
1 forces a Left outer join in the query
With EAGER fetch types, a nested criteria should work for this case:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.createCriteria("formApprovals")
.add(Restrictions.eq("latestApproval", true))
.list();
return result;
}
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