What I need to write in JoinColumn? - java

Sorry for my question. Really can`t understand my mistake.
I have a Hibernate relations between two classes but when I run it logs give me this error:
org.hibernate.AnnotationException: mappedBy reference
an unknown target entity property: model.pilgi.Pilgi.PilgiDocument in model.pilgi_doc.PilgiDocument.pilgi
Code of the fisrt class PilgiDocument:
#Entity
#Table(name = "pilgi_document")
public class PilgiDocument {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private BigInteger pdocument_id;
#OneToMany(mappedBy = "PilgiDocument")
private List<Pilgi> pilgi = new ArrayList();
Pilgi class is here:
#Entity
#Table(name = "pilgi")
public class Pilgi {
#JoinColumn(name = "pilga")
#ManyToOne(fetch = FetchType.LAZY)
private PilgiDocument pdocument_id;

The error your have says that Hibernate doesn't find the PilgiDocument attribute in the class Pilgi: you don't have it but you have a pdocument_id property, that is an instance of PilgiDocument
In your PilgiDodument class, what you need to write is :
#Entity
#Table(name = "pilgi_document")
public class PilgiDocument {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private BigInteger pdocument_id;
#OneToMany(mappedBy = "pdocument_id")
private List<Pilgi> pilgi = new ArrayList();
You indicate the name of the attribute of your Pilgi class that represent the PilgiDocument attribute
In your Pilgi class, you need to write, in your #JoinColumn the name of the database column used as your foreign key for your PilgiDocument

Related

Invalid Identifier While Joining Tables in JPA

I am trying to join 3 tables in JPA. When i am trying to associate CRL_IC_IMPORT_TRANS table i am getting error as Invalid Identifier as shown below
from
crl_ic investorco0_
left outer join
crl_ic_import_trans icimporttr1_
on investorco0_.icimport_trans_event_id=icimporttr1_.event_id
left outer join
crl_ic_order investorco2_
on investorco0_.current_order_id=investorco2_.id
"INVESTORCO0_"."ICIMPORT_TRANS_EVENT_ID": invalid identifier
Edit
from
crl_ic investorco0_
left outer join
crl_ic_order investorco1_
on investorco0_.current_order_id=investorco1_.id
Error:
Provided id of the wrong type for class ICImportTrans. Expected: class java.lang.Long, got class java.lang.String
Why its going to primary key in ICImportTrans class even after i mapped to a non PK ?
Below are my 3 tables and its keys. What is the mistake i am doing .
#Table(name = "CRL_IC")
public class ICLoanOrder {
#Id
#Column(name="EVENT_ID")
String id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "EVENT_ID",referencedColumnName = "eventId" )
ICImportTrans iCImportTrans;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
ICOrder currentOrder;
}
#Table(name = "CRL_IC_ORDER")
public class ICOrder implements Serializable {
#Id
#GenericGenerator(name = "UUIDGenerator", strategy = "uuid2")
#GeneratedValue(generator = "UUIDGenerator")
#Type(type = "uuid-char")
UUID id;
#ManyToOne(fetch = FetchType.LAZY)
#JsonIgnore
#JoinColumn(name="EVENT_ID")
ICLoanOrder iCLoanOrder;
}
#Table(name = "CRL_IC_IMPORT_TRANS")
public class ICImportTrans implements Serializable {
#Id
#GeneratedValue(strategy= GenerationType.SEQUENCE, generator="SEQ1")
#SequenceGenerator(name="SEQ1",sequenceName = "SEQ_IC_IMPORT",allocationSize = 1)
#Column(name="PROCESS_ID")
private Long processId;
private String eventId;
}
The default name of the column should be iCImportTrans_id.
If you want to change it to icimport_trans_event_id you need to specify it in the #JoinColumn
#Table(name = "CRL_IC")
public class ICLoanOrder {
...
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "icimport_trans_event_id", referencedColumnName = "eventId")
ICImportTrans iCImportTrans;
...
}
Provided id of the wrong type for class ICImportTrans. Expected: class java.lang.Long, got class java.lang.String
What kind of mapping are you trying to achieve?
In ICLoanOrder you mapped the id column and the association column to the same name EVENT_ID. I guess you want to use ICImportTrans.eventId as id of ICLoanOrder.
This willwork if you don't care about having an id field:
#Entity(name="LoanOrder")
#Table(name = "CRL_IC")
public static class ICLoanOrder implements Serializable{
#Id
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "EVENT_ID", referencedColumnName = "eventId")
ICImportTrans iCImportTrans;
}
Normally, you would use #MapsId, but it seems to ignore the referencedColumn attribute and gives the same error.

How do I make a generic #OneToMany mapping of concrete classes using their super type?

I have a base abstract class defined like so :
#MappedSuperclass
public abstract class State implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "stateCode")
private String code;
}
The concrete classes such as StateA, StateB... StateZ were defined like so:
#Entity
#Table(name = "stateA")
public class StateA extends State implements serializable{
}
There's also a Region class like so:
#Entity
#Table(name = "region")
public class Region {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name = " regionCode")
private String regionCode;
}
Each of the concrete State classes references the Region class in the database.
However, I'm struggling to have a OneToMany mapping like this in the Region class:
#OneToMany(mappedBy = "region", cascade= cascadeType.ALL)
private Set<State> state = new HashSet<>()
And the following ManyToOne mapping in the abstract State class:
#ManyToOne
#JoinColumn(name = "regionId")
private Region region;
but it wouldn't work since State is an unmapped entity. Is there a way I can make a generic mapping of concrete State in the Region class without having to declare each of the concrete classes?
I think the problem is here:
#OneToMany(mappedBy = "region", cascade= CascadeType.ALL)
private Set<State> state = new HashSet<>();
You could not use #OneToMany association to List
of State class cause it's not Entity. You should use a collection of entities that inherits from State class.
I think your code will be fine if you change the code above into that one:
#OneToMany(mappedBy = "region", cascade= CascadeType.ALL)
private Set<StateA> state = new HashSet<>();
You should change inheritance strategy, I recommend you to use single table strategy, so in my opinion you you should transform your 'State' class to this:
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class State implements Serializable {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name = "stateCode")
private String code;
#ManyToOne
#JoinColumn(name = "regionId")
private Region region;
}

JPA Hibernate Annotation Issue

I have three Entities i'm modeling and am having issues with the associated annotations. I basically have a class that I intend on returning to the caller, a nested listed of Project's and the Project can contain a nested list of Endpoint's. It's a top-level has-a one-to-many, then the nested one-to-many has two one-to-many's.
I've played with #JoinColumn annotations, i've attempted to put a #ManyToOne on the other side of the OneToMany's (but it doesn't like that it's a Long..). I'm just fairly new and unsure on how to do this. I think the mappedById is the solution, but i'm uncertain.
Main Issue: This code allows me to "save" to the database, but upon retrieval, the list of Project's inside the DownDetectorPackage is empty.
A CascadeType.ALL throws referential integrity errors that I don't completely understand.
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Builder
public class DownDetectorPackage {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#OneToMany(mappedBy="id",fetch = FetchType.EAGER)
private List<Project> projects;
#Temporal(TemporalType.DATE)
private Date dateJobsLastRan;
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class Project{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String projectName;
#OneToMany(mappedBy="id")
private List<Service> externalDependencies;
#OneToMany(mappedBy="id")
private List<Service> endpoints;
}
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class Service {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String url;
private Boolean endpointIsUp;
private String serviceName;
}
You should be using #JoinColumn instead of mappedBy. MappedBy can be used when you have used #ManyToOne in the other class too, which you haven't.
So your final class should look something like this (this is applicable for the other classes too which you have mentioned) :
public class DownDetectorPackage {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#JoinColumn(name = "downDetectorPackageId")
#OneToMany(fetch = FetchType.EAGER)
private List<Project> projects;
#Temporal(TemporalType.DATE)
private Date dateJobsLastRan;
Also, remember to state the parent object name in #JoinColumn annotation, since it would create a column for that foreign key.
You should mark every join column as JoinColumn denotating the referenced column from the other entity. Then, you are supposed to say which relation type are using this column.
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String projectName;
#JoinColumn(referencedColumnName = "id")
#OneToMany(fetch = FetchType.LAZY)
private ExternalDependencyEntity externalDependencies;
#JoinColumn(referencedColumnName = "id")
#OneToMany(fetch = FetchType.LAZY)
private EndpointEntity endpoints;
}
Finally, note that in a relational database, every fk column can takes only 1 value (pk of referenced entity id), so, on your entity, you should mark the data type as the entity you are refering to and no as a collection.
I think this sould solve your problem.

How do I map all these tables with Hibernate?

I have a table PATIENT which has some fields. There's also a CONTACT table that has a field called 'patientId' that needs to store PATIENT's ID (which is autogenerated), and a PATIENT_CONTACT table that only relates the two tables.
Now, here comes the tricky part. There are three other tables: CONTACT_ADDRESS, CONTACT_PHONE, CONTACT_EMAIL. A row in CONTACT will have the same ID as one (and only one) of CONTACT_ADDRESS, CONTACT_PHONE and CONTACT EMAIL. How do I get this all to work?
I have tried so many approaches, this is what I have right now:
#Entity
#Table(name = "patient", schema = "patient")
public class PatientEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
//... more fields
#OneToOne
private ContactEmailEntity contactEmailEntity;
#OneToOne
private ContactAddressEntity contactAddressEntity;
#OneToOne
private ContactPhoneEntity contactPhoneEntity;
}
The three CONTACT_* classes are similar and they look like this:
#Table(name = "contact_address", schema = "patient")
public class ContactAddressEntity {
#Id
#Column(name = "id")
private Long id;
// ... more fields
#OneToOne(cascade = {CascadeType.ALL})
#MapsId
private ContactEntity contact;
}
And my CONTACT class looks like this:
#Table(name = "contacto", schema = "paciente")
public class ContactEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
//... more fields
Can you see things that don't look right or could be done better? I get all sorts of errors with every approach. My latest one is:
ERROR: column patientent0_.contact_address_entity_contact_id does not exist
when trying to do a simple patient find. Please, any help is appreciated!

Hibernate mappedBy="table_name" is confusing one

I have two domain models as follows,
#Entity
#Table(name = "candidate") // lowercase-for-database-conventions
public class Candidate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
.
.
.
#OneToOne(mappedBy="Candidate", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
//above here, mappedBy has Class name to map, as OO Design suggests.
private Ctc ctc;
}
When I try to run the application, it gives me this exception.
org.hibernate.AnnotationException: Unknown mappedBy in: com.hrsystem.model.Candidate.ctc, referenced property unknown: com.hrsystem.model.Ctc.Candidate
But if I put the value of mappedBy exactly as database-convention (i.e. lower case letters as in #Table(name="candidate") ), it works perfectly fine.
So my question is, why we should encourage database-convention driven development though we are using Object Oriented Design?
UPDATE---
Here is my Ctc.java entity.
#Entity
#Table(name = "ctc")
public class Ctc {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private double basic;
private double hra;
private double da;
#OneToOne
#JoinColumn(name = "candidate_id")
private Candidate candidate;
}
and getters and setters below it..!!
you do not put the table name in the mappedBy, you put the name of the reference to your object.
So in your case
#OneToOne(mappedBy="candidate", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
//above here, mappedBy has Class name to map, as OO Design suggests.
private Ctc ctc;
We would expect Ctc class to be something like that
public class Ctc {
//other properties
#OneToOne
#JoinColumn
private Candidate candidate

Categories

Resources