I have the following domain classes:
#Entity
#Table(name="ADDRESSBOOK_FIELD")
#Inheritance(strategy=InheritanceType.JOINED)
public abstract class AbstractAddressbookField {
private int dbID;
private Addressbook addressbook;
public AbstractAddressbookField() {
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return dbID;
}
public void setId(int id) {
this.dbID = id;
}
#ManyToOne
#JoinColumn(nullable=false)
public Addressbook getAddressbook() {
return addressbook;
}
public void setAddressbook(Addressbook addressbook) {
this.addressbook = addressbook;
}
}
.
#Entity
#Table(name="DATE_FIELD")
public class DateField extends AbstractAddressbookField {
public DateField() {
}
}
.
#Entity
#Table(name="NEW_ADDRESSBOOK")
public class Addressbook {
private int dbID;
private Set<DateField> dateFields = new HashSet<DateField>();
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getDbID() {
return dbID;
}
public void setDbID(int dbID) {
this.dbID = dbID;
}
#OneToMany(mappedBy="Addressbook", cascade={CascadeType.ALL})
public Set<DateField> getDateFields() {
return dateFields;
}
public void setDateFields(Set<DateField> dateFields) {
this.dateFields = dateFields;
}
}
My packages are being scanned correctly to pick up all the mappings, but I am getting the following exception:
Caused by: org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: fields.DateField
I am unsure as to why this is, as the class is clearly mapped to.
Looks like that entity is not mapped in your ' persistence.xml' file.
I think you problem is the capital letter in:
#OneToMany(mappedBy="Addressbook", cascade={CascadeType.ALL})
public Set<DateField> getDateFields() {
return dateFields;
}
use mappedBy="addressbook instead.
Related
I have the following classes:
#Entity(name = "focusoc_orbit")
#Data
public class OrbitAdapter extends Adapter{
#Id
private String id;
...
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
...
}
And,
#Entity(name = "focusoc_conjunction")
#Data
public class ConjunctionAdapter extends Adapter {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "target_id")
private OrbitAdapter target;
#ManyToOne
#JoinColumn(name = "chaser_id")
private OrbitAdapter chaser;
...
public OrbitAdapter getTarget(){
return target;
}
public void setTarget(OrbitAdapter target){
this.target = target;
}
public String getChaserId(){
return chaserId;
}
public void setChaser(OrbitAdapter chaser){
this.chaser = chaser;
}
...
}
Also I defined the Repository:
public interface ConjunctionRepository extends PagingAndSortingRepository<ConjunctionAdapter, Long> {
public ConjunctionAdapter findByTargetAndChaserAndTimeOfCloseApproach(String target, String chaser, Date timeOfCloseApproach);
}
When I try to make the call,
ConjunctionAdapter c = conjunctionRepository.findByTargetAndChaserAndTimeOfCloseApproach(targetId, chaserId, timeOfCloseApproach());
It returns the error:
org.hibernate.property.access.spi.PropertyAccessException: Error
accessing field [private java.lang.String
gcs.fds.focusoc.adapter.OrbitAdapter.id] by reflection for persistent
property [gcs.fds.focusoc.adapter.OrbitAdapter#id] : 02035A"
I tried a lot of differents solutions that I found but it does not work for me. Any help?
I solved it !
Changing the annotation #Data of the classes for #Table with the table name. So,
#Entity
#Table(name = "focusoc_orbit")
public class OrbitAdapter extends Adapter{
#Id
private String id;
...
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
...
}
And,
#Entity
#Table(name = "focusoc_conjunction")
public class ConjunctionAdapter extends Adapter {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "target_id")
private OrbitAdapter target;
#ManyToOne
#JoinColumn(name = "chaser_id")
private OrbitAdapter chaser;
...
public OrbitAdapter getTarget(){
return target;
}
public void setTarget(OrbitAdapter target){
this.target = target;
}
public String getChaserId(){
return chaserId;
}
public void setChaser(OrbitAdapter chaser){
this.chaser = chaser;
}
...
}
And doing this it returns me the error,
java.lang.IllegalArgumentException: Parameter value [02035A] did not
match expected type [gcs.fds.focusoc.adapter.OrbitAdapter (n/a)]
So I added the annotation #Query into the Repository to specify which things has to be searched in the database,
public interface ConjunctionRepository extends PagingAndSortingRepository<ConjunctionAdapter, Long> {
#Query("SELECT c FROM ConjunctionAdapter c WHERE c.target.id = :target AND c.chaser.id = :chaser AND c.timeOfCloseApproach = :timeOfCloseApproach")
public ConjunctionAdapter findByTargetAndChaserAndTimeOfCloseApproach(String target, String chaser, Date timeOfCloseApproach);
}
And solved!
I am trying to perform a fetch using Criteria API with restrictions on the variable of an embedded entity. But I am getting the below error,
org.hibernate.QueryException: could not resolve property: cpm of: org.sorabh.SystemEnt
Below is my SystemEnt entity,
#Entity
#Table(name="system")
public class SystemEnt implements Serializable{
#Id
#Column(name="pmTpId", nullable = false)
private int id;
#Column(name="pmMeasureId", nullable = false)
private int pmMeasureId;
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="pmMeasureId", insertable=false, updatable=false)
private Cpm cpm;
private String mapper;
public int getId() {
return id;
}
public int getPmMeasureId() {
return pmMeasureId;
}
public Cpm getCpm() {
return cpm;
}
public String getMapper() {
return mapper;
}
public void setId(int id) {
this.id=id;
}
public void setPmMeasureId(int pmMeasureId) {
this.pmMeasureId=pmMeasureId;
}
public void setCpm(Cpm cpm) {
this.cpm=cpm;
}
public void setMapper(int mapper) {
this.mapper=mapper;
}
My CpmMeas contains
#Entity
#Table(name="cpm")
public class Cpm implements Serializable{
#Id
#Column(name="pmMeasureId", nullable = false)
private int pmMeasureId;
#Column(nullable=false)
private int pmGranularity
//getters and setters
public void setPmMeasureId(int pmMeasureId) {
this.pmMeasureId=pmMeasureId;
}
public int getPmMeasureId() {
return pmMeasureId;
}
public void setPmGranularity(int pmGranularity) {
this.pmGranularity=pmGranularity;
}
public int getPmGranularity() {
return pmGranularity;
}
I do the below in my serviceImpl:
Criteria cr = session.createCriteria(SystemEnt.class);
cr.add(Restrictions.like("mapper", "Test", MatchMode.START));
cr.add(Restrictions.eq("cpm.pmGranularity", 1));
I have tried using aliases as suggested in a few other posts on SO, but it doesn't seem to solve the issue.
Also, it is not having issues in resolving mapper, i.e only the nested entities and corresponding variables are not getting resolved.
Use alias , as
Criteria cr = session.createCriteria(SystemEnt.class);
cr.createAlias("cpm","cpm");
cr.add(Restrictions.like("mapper", "Test", MatchMode.START));
cr.add(Restrictions.eq("cpm.pmGranularity", 1));
anyway the field mapper should be a String, in your sample code it is defined as an int.
I tested and without a doubt it works fine.
I have a class called jobprofile, which contains the following OneToMany Relation:
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "profile")
private List<JobLanguageProficiency> jobLanguageProficiency;
The referenced class "JobLanguageProficiency" looks like this:
package ch.alv.jobmatch.entity.aux;
import ch.alv.jobmatch.entity.job.Jobprofile;
import javax.persistence.*;
#Entity
#Table(name = "job_language_proficiency")
public class JobLanguageProficiency {
#Id
private int id;
#ManyToOne
#JoinColumn(name = "jobprofile_jobprofile_id")
private Jobprofile profile;
#OneToOne
private Languages languages;
#OneToOne
private LangProficiency langProficiency;
public Languages getLanguages() {
return languages;
}
public void setLanguages(Languages languages) {
this.languages = languages;
}
public LangProficiency getLangProficiency() {
return langProficiency;
}
public void setLangProficiency(LangProficiency langProficiency) {
this.langProficiency = langProficiency;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Jobprofile getProfile() {
return profile;
}
public void setProfile(Jobprofile profile) {
this.profile = profile;
}
}
Basically, it just contains two references to a language, and a proficiency for it.
When I try to create/persist a jobprofile, it fails as soon as it tries to insert the language data in the database.
This is the error:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException:
Could not write content: (was java.lang.NullPointerException) (through
reference chain:
org.springframework.data.rest.webmvc.json.["content"]); nested
exception is com.fasterxml.jackson.databind.JsonMappingException: (was
java.lang.NullPointerException) (through reference chain:
org.springframework.data.rest.webmvc.json.["content"])
I suspect the source of the error lies in the JSON, since the OneToMany Relation works perfectly when I insert the data manually.
The relevant part of the JSON looks like this:
job_language_proficiency: Array[1]
0: Object
languages: "http://localhost:9000/api/languages/de"
proficiency_code: "http://localhost:9000/api/langproficiency/C1"
Any ideas why this doesn't work?
EDIT: Updated the JSON so it contains objects instead of links.
LangProficiency entity:
package ch.alv.jobmatch.entity.aux;
import javax.persistence.*;
#Entity
#Table(name = "LangProficiency")
public class LangProficiency {
#Id
#Column(name = "proficiency_code")
private String proficiency_code;
private String description_de;
private String description_fr;
private String description_it;
private String description_en;
public String getProficiency_code() {
return proficiency_code;
}
public void setProficiency_code(String proficiency_code) {
this.proficiency_code = proficiency_code;
}
public String getDescription_de() {
return description_de;
}
public void setDescription_de(String description_de) {
this.description_de = description_de;
}
public String getDescription_fr() {
return description_fr;
}
public void setDescription_fr(String description_fr) {
this.description_fr = description_fr;
}
public String getDescription_it() {
return description_it;
}
public void setDescription_it(String description_it) {
this.description_it = description_it;
}
public String getDescription_en() { return description_en; }
public void setDescription_en(String description_en) { this.description_en = description_en; }
}
Languages entity:
package ch.alv.jobmatch.entity.aux;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Table(name = "Languages")
public class Languages implements Serializable {
#Id
#Column(name = "languages")
private String languages;
private String description_de;
private String description_fr;
private String description_it;
private String description_en;
public String getLanguages() {
return languages;
}
public void setLanguages(String languages) {
this.languages = languages;
}
public String getDescription_de() {
return description_de;
}
public void setDescription_de(String description_de) {
this.description_de = description_de;
}
public String getDescription_fr() {
return description_fr;
}
public void setDescription_fr(String description_fr) {
this.description_fr = description_fr;
}
public String getDescription_it() {
return description_it;
}
public void setDescription_it(String description_it) {
this.description_it = description_it;
}
public String getDescription_en() { return description_en; }
public void setDescription_en(String description_en) { this.description_en = description_en; }
}
Your JSON structure should match your Java Mapping, otherwise your object won't be persisted by your ORM, that's why you are getting such Mapping error.
In your case in your Entity you have a relationship with two entities that should be objects in your JSON:
#OneToOne
private Languages languages;
#OneToOne
private LangProficiency langProficiency;
But in your JSON, you have set those two objects as simple strings:
languages: "http://localhost:9000/api/languages/de"
proficiency_code: "http://localhost:9000/api/langproficiency/C1"
They should be matching Languages and langProficiency objects, and proficiency_code should be named langProficiency respectively like your Java attribute.
I'm developing an application using java with hibernate 4.2.6 and spring 4.0.1. My application is a REST FULL application. for this I use jackson. My entities are as follow:
Calk.java:
#Entity
public class Calk {
#Id
#GeneratedValue
private Long id;
#OneToMany(mappedBy="calk", fetch=FetchType.LAZY)
List<BaseLayer> baseLayer = new ArrayList<BaseLayer>();
public void addBaseLayer(BaseLayer baseLayer){
this.baseLayer.add(baseLayer);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#JsonIgnore
public List<BaseLayer> getBaseLayer() {
return baseLayer;
}
public void setBaseLayer(List<BaseLayer> baseLayer) {
this.baseLayer = baseLayer;
}
}
BaseLayer.java:
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="layer")
#JsonSubTypes(
{
#JsonSubTypes.Type(value=PointLayer.class, name="point")
})
#DiscriminatorValue("BaseLayerDiscriminator")
public class BaseLayer {
#Id
#GeneratedValue
protected Long gid;
#ManyToOne(fetch = FetchType.LAZY)
protected Calk calk;
public Long getGid(){
return gid;
}
public void setGid(Long gid){
this.gid = gid;
}
#JsonIgnore
public Calk getCalk(){
return calk;
}
public void setCalk(Calk calk){
this.calk = calk;
}
}
Now I have a class that extends from BaseLayer.java as follow:
PointLayer.java:
#Entity
#DiscriminatorValue("PointDiscriminator")
public class PointLayer extends BaseLayer{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now I create a json as follow and then send it to a controller:
{"layer": "point", "calk":{"id":1}, "name": "itsme"}
Now the controller defines as follow:
#RequestMapping("\test")
public String test(#RequestBody BaseLayer baseLayer){
System.out.println(baseLayer.getName());// this print "itsme"
Calk calk = baseLayer.getCalk();//it return null
if(calk == null)
return "its null";
else
return "its not null";
}
when we call the controller it return its not null. The calk should not be null.
Where is the problem?
Update:
When I remove #JsonIgnore at getCalk, It work fine. But Why? I want to ignore getCalk but NOT ignore setCalk.
#JsonIgnore in follow:
#JsonIgnore
public List<BaseLayer> getBaseLayer() {
return baseLayer;
}
set Ignore to following by default:
public void setBaseLayer(List<BaseLayer> baseLayer) {
this.baseLayer = baseLayer;
}
You must add #JsonProperty("baseLayer") On top of set function as follow:
#JsonProperty("baseLayer")
public void setBaseLayer(List<BaseLayer> baseLayer) {
this.baseLayer = baseLayer;
}
I have a many-to-many relationship between EnfInspPrgm entity and EnfInspPmSc entity.
Here are the entity classes
public class EnfInspPrgm implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="PRM_ID")
private long prmId;
#Column(name="AREA_ID")
private long areaId;
//bi-directional many-to-one association to EnfInspPmSc
#OneToMany(mappedBy="enfInspPrgm")
private List<EnfInspPmSc> enfInspPmScs;
public EnfInspPrgm() {
}
public long getPrmId() {
return this.prmId;
}
public void setPrmId(long prmId) {
this.prmId = prmId;
}
public long getAreaId() {
return this.areaId;
}
public void setAreaId(long areaId) {
this.areaId = areaId;
}
public List<EnfInspPmSc> getEnfInspPmScs() {
return this.enfInspPmScs;
}
public void setEnfInspPmScs(List<EnfInspPmSc> enfInspPmScs) {
this.enfInspPmScs = enfInspPmScs;
}
public EnfInspPmSc addEnfInspPmSc(EnfInspPmSc enfInspPmSc) {
getEnfInspPmScs().add(enfInspPmSc);
enfInspPmSc.setEnfInspPrgm(this);
return enfInspPmSc;
}
public EnfInspPmSc removeEnfInspPmSc(EnfInspPmSc enfInspPmSc) {
getEnfInspPmScs().remove(enfInspPmSc);
enfInspPmSc.setEnfInspPrgm(null);
return enfInspPmSc;
}
}
#Entity
#Table(name="ENF_INSP_PM_SC")
public class EnfInspPmSc implements Serializable {
private static final long serialVersionUID = 1L;
//bi-directional many-to-one association to InspectionSource
#ManyToOne(optional=false)
#JoinColumn(name="ENF_INSP_SOURCE_ID")
private InspectionSource inspectionSource;
#Column(name="ENF_INSP_PRM_SRC_ID")
private long enfInspPrmSrcId;
#ManyToOne
#JoinColumn(name="PRM_ID")
private EnfInspPrgm enfInspPrgm;
public EnfInspPmSc() {
}
}
#Entity
#Table(name = "REF_ENF_INSP_SOURCE")
public class InspectionSource implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ENF_INSP_SOURCE_ID")
private Integer id;
// bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name = "CREATED_BY_USER_ID")
private User createdUser;
// bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name = "MODIFIED_BY_USER_ID")
private User modifiedUser;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public User getCreatedUser() {
return createdUser;
}
public void setCreatedUser(User createdUser) {
this.createdUser = createdUser;
}
public String getCreatedByName() {
return createdByName;
}
public void setCreatedByName(String createdByName) {
this.createdByName = createdByName;
}
public User getModifiedUser() {
return modifiedUser;
}
public void setModifiedUser(User modifiedUser) {
this.modifiedUser = modifiedUser;
}
}
I am creating a JPA repository for selecting the EnfInspPrgm entities. But itis causing an error
Invalid identifier for enfInspPrgm, ENF_INSP_SOURCE_ID
Please help me and resolve this issue.
Your code seems missing some declaration. For example EnfInspPrgm is not annotatted with #Entity.
Also, In EnfInspPmSc you didn't put getter and setter for the fields. Put getEnfInspPrgm and setEnfInspPrgm. Do the same for the other fields.
Note that JPA declartions will be translated in all cases into native sql. The owner of the relationship is always the many side which has a FK to the one side. So, If EnfInspPmSc don't have those setters and getters you won't be able to get access to any data in both tables.