Unable to find column with logical name hibernate - java

I have table where to 2 columns join another relations. I was tried join this with #JoinColumns but i getting error Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name CLASS_ID in table item_sub_class
I looked in h2-console and in table item_sub_class i see column class_id. Look screenshot
This is my relations code from Item class
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Item implements Serializable {
#Id
private Long id;
private String description;
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "class_id")
private ItemClass itemClass;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name= "subclass_id",referencedColumnName = "subclass"),
#JoinColumn(name= "class_id",referencedColumnName = "class_id")
})
private ItemSubClass itemSubClass;
private Long sellPrice;
//getter and setters
}
And ItemSubClass
#Entity
public class ItemSubClass implements Serializable {
#Id
#GeneratedValue
private Long id;
#JsonProperty("subclass")
#Column(name = "subclass")
private Long subclass;
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "class_id")
private ItemClass itemClass;
//getters and setters
}
Some one can explain what is bad and why this relation throwing me error? This is possible to fix this?

Related

HQL query doesn't order by other mapped entity criteria

I have the following entities in a Hibernate - Spring proyect.
Member:
#Entity
#Table(name = "member")
public class Member implements Serializable {
private static final long serialVersionUID = 1871629487715861212L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "ident_doc")
private String identDoc;
#Column(name = "join_date")
private String joinDate;
private String nickname;
#OneToOne(mappedBy = "member")
private MemberContact memberContact;
#OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<MemberChapterLog> memberChapterLogs;
#OneToMany(mappedBy = "member")
private List<ChapterOfficers> chapterOfficers;
#OneToOne(mappedBy = "contactMember", cascade = CascadeType.ALL)
private Chapter asChapterContact;
Chapter:
#Entity
#Table(name = "chapter")
#NamedQuery(
name = "Chapter_Get_Detailed_Members_List",
query = "from MemberChapterLog where chapter.id = :paramChapter and active = true "+
"order by member.lastName asc")
public class Chapter implements Serializable {
private static final long serialVersionUID = -8387387246818721664L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String initials;
#Column(name ="chap_name")
private String chapName;
#ManyToOne
#JoinColumn(name = "category")
private ChapCategory category;
#OneToOne
#JoinColumn(name = "contact_member")
private Member contactMember;
#OneToOne(mappedBy = "chapter", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private ChapterContact chapterContact;
#OneToMany(mappedBy = "chapter")
private List<MemberChapterLog> memberChapterlogs;
#OneToMany(mappedBy = "chapter")
private List<ChapterOfficers> chapterOfficers;
MemberChapterLog:
#Entity
#Table(name = "member_chapter_log")
public class MemberChapterLog implements Serializable {
private static final long serialVersionUID = -643503606583240644L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "member_id")
private Member member;
#ManyToOne
#JoinColumn(name = "chapter_id")
private Chapter chapter;
#Column(name = "log_date")
private String logDate;
private String comment;
private boolean active;
I want to get a list of the active members of certain chapter (passed as ':paramChapter'), order by their last name. When I run the named query at chapter ("from MemberChapterLog where chapter.id = :paramChapter and active = true order by member.lastName asc") it generates the following error:
org.hibernate.HibernateException: Errors in named queries:
Chapter_Get_Detailed_Members_List failed because of: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: member near line 1, column 105 [from dev.xarlsr.cdt.entity.MemberChapterLog where chapter.id = :paramChapter and active = true order by member.lastName asc]
If I delete the order by member.lastName it works properly (without any order, byt the way).
I tried to change the mapping by changing the tables foreign keys and the ownership, but doesn't work. I tried to change the fetch type without results. What am I doing wrong?
The problem is the mapping:
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "member_id")
private Member member;
member is a keyword in JPQL/HQL and soft-keyword handling was only introduced in Hibernate 6, so you will need to change the name of the field to e.g. memberAssociation and the query condition to ... order by memberAssociation.lastName asc

Hibernate #ManyToMany with extra columns

So I've been trying the solutions out there to map a ManyToMany relationship with extra columns but none of them is working for me and I don't know what am I doing wrong.
The Many to Many relationship is between Patient and Disease (a Patient can have multiple diseases and a Disease can be suffered by many Patients). The time attribute means "the type of the disease" (acute, chronic...)
My classes are:
#Entity
#Table(name="patient")
public class Patient{
#Id
#NotNull
#Column(name="nss")
private String NSS;
//Some attributes
#OneToMany(mappedBy = "patient")
private Set<PatientDisease> diseases = new HashSet<PatientDisease>();
//Empty constructor and constructor using fields omitted
//Getters and setters ommited
}
,
#Entity
#Table(name="disease")
public class Disease{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#OneToMany(mappedBy = "disease")
private Set<PatientDisease> patients = new HashSet<PatientDisease>();
//Constructors and getters and setters ommited for brevity
}
Associated class
#Entity
#Table(name = "Patient_Disease")
#IdClass(PatientDiseaseID.class)
public class PatientDisease{
#Id
#ManyToOne(fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
#JoinColumn(name = "nssPatient", referencedColumnName = "id")
private Patient patient;
#Id
#ManyToOne(fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
#JoinColumn(name = "diseaseID", referencedColumnName = "id")
private Disease disease;
#Column(name="time")
private String time;
//GETTERS AND SETTERS OMMITED FOR BREVETY. Constructor NOT Needed following the example
}
The id class:
#Embeddable
public class PatientDiseaseId implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "nssPatient")
private String patient;
#Column(name = "diseaseID")
private Integer disease;
//getters and setters
//hashCode and equals
}
My main app:
...
List<Diseases> diseases = sesion.createQuery("from Disease").getResultList();
System.out.println("Diseases: ");
for(Disease d: diseases) {
System.out.println(d.getName());
for(PatientDisease pd: e.getPatientDisease()) {
System.out.println(pd.getPatient().toString());
}
}
...
When running the main App I get the exception on line 5 (2nd for loop):
Exception in thread "main" org.hibernate.PropertyAccessException: Could not set field value [1] value by reflection : [class entities.PatientDisease.diseases] setter of entities.PatientDisease.diseases
I have tried some solutions here in Stack Overflow an some others that I found on the Internet, but I can't get them to work and I don't know why
Because you are using #IdClass you don't need to annotate PatientDiseaseId with #Embedded and #Column. And you have to refer to the entities.
This is what it should look like:
public class PatientDiseaseId implements Serializable {
private static final long serialVersionUID = 1L;
private Patient patient;
private Disease disease;
//getters and setters
//hashCode and equals
}

Map/Access entities with composite key

In my application I have 3 core classes as described below.
public class Semana {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Integer series;
private String observacao;
private Integer ordenacao;
#OneToMany(mappedBy = "semana")
#JsonBackReference
#OrderBy("ordenacao asc ")
private List<TreinoOrdenado> treinoOrdenados;
}
public class TreinoOrdenado {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "id_semana")
private Semana semana;
#ManyToOne
#JoinColumn(name = "id_treino")
private Treino treino; // can be repeated in the database but with different "ordenacao"
private Integer ordenacao;
}
#Table(name = "exercicio_ordenado")
public class ExercicioOrdenado {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "id_treino")
#JsonBackReference
#ToString.Exclude
private Treino treino;
#ManyToOne
#JoinColumn(name = "id_exercicio")
private Exercicio exercicio;
private Integer ordenacao;
#ManyToOne
#JoinTable(name = "parametro")
private Parametro parametro;
}
And this Parametro class which is a relationship between those 3 classes.
public class Parametro {
#EmbeddedId
private ParametroId parametroId = new ParametroId();
#MapsId("semana")
#OneToOne
#JoinColumn(name = "semana_id")
private Semana semana;
#MapsId("treino")
#OneToOne
#JoinColumn(name = "treino_id")
private TreinoOrdenado treino;
#MapsId("exercicio")
#OneToOne
#JoinColumn(name = "exercicio_id")
private ExercicioOrdenado exercicio;
private Integer series;
private String repeticoes;
private String observacao;
}
public class ParametroId implements Serializable {
#Column(name = "semana_id")
private Long semana;
#Column(name = "treino_id")
private Long treino;
#Column(name = "exercicio_id")
private Long exercicio;
}
So, here is my problem. I want to be able to access the Parametro from it's parent class ExercicioOrdenado, but in order to be distinguishable in the database the class Parametro needs the reference from the other two (Semana, TreinoOrdenado).
With my current mapping I got this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK73ewcy2r50kw71o4he51dkolv:parametro
[parametro_exercicio_id,parametro_semana_id,parametro_treino_id])) must have same number of columns as the referenced primary key (parametro [id])
I can persist paremetros in the database with:
parametros.setSemana(semana);
parametros.setExercicio(exercicioOrdenado);
parametros.setTreino(treinoOrdenado);
parametroRepository.save(parametros);
But I can't retrieve from ExercicioOrdenado with the mapping.
I don't know the right approach to do this.
I think i now a way...
To do this we can use #Embeddable and #EmbeddedId annotation.
In this link have exemples.
https://www.baeldung.com/jpa-composite-primary-keys
#Entity
public class Parametro {
#EmbeddedId
private ParametroId parametroId;
#OneToOne
#JoinColumn(name = "exercicio_id")
#ForeignKey(name = "fk_exercicio_id")
private ExercicioOrdenado exercicio;
#OneToOne
#JoinColumn(name = "semana_id")
#ForeignKey(name = "fk_semana_id")
private Semana semana;
#OneToOne
#JoinColumn(name = "treino_id")
#ForeignKey(name = "fk_treino_id")
private TreinoOrdenado treino;
private Integer series;
private String repeticoes;
private String observacao;
}
#Embeddable
public class ParametroId {
private log id;
private log semana;
private log treino;
private log exercicio;
}
I believe that this is the way to create a personalized primary key using jpa. I have not tested the relationships of entities in the primary key. I know that there is more than one form to do that.
JPA #OneToOne with Shared ID -- Can I do this Better?

Spring data jdbc - Specific join, specific mapping

I've got following two tables:
Customer
id
name
Order
id
product_name
customer_id
with a 1 to 1 relation
and java entities:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
and a controller
#Controller
public class MyController{
//...
#GetMapping("/")
public String getmap(Model m){
System.out.println(repository.findAll()) //prints "nullrows" due to wrong sql statement
return "mytemplate";
}
}
my current issue is, that spring is executing following sql statement:
SELECT Order.id, Order.product_name, Customer.id, Customer.name
FROM Order LEFT OUTER JOIN Customer ON Customer.id = Order.id
what i actually want is to join on Customer.id = Order.customer_id while leaving the classes as they are i.e. the customer reference needs to stay in order.
i've tried every annotation that i could find so far and have made no progress.
EDIT:
I am not allowed to use jpa/hibernate
One workaround is to do the following:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long customerId;
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
causing this to automatically join on Customer.id = Order.customer_id
This does not look like a good fix however.
You can use #OneToOne and #JoinColumn annotations for your One-to-One relationship:
#Data
public class Customer{
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id", referencedColumnName = "id")
private Order order;
}
#Data
public class Order{
#Id
#Column(name = "id")
private Long id;
#Column(name = "product_name")
private String productName;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customer;
}

Hibernate delete row and foreign key row ManyToOne

I have the following two classes, one ReqCandAssociation can have many Comments and it is mapped like so. I need to figure out a way that when I delete a ReqCandAssociation it deletes all of its associated comments. Thanks
#Entity
#Table(name = "candidate_jobReq")
public class ReqCandAssociation implements Serializable {
#Id
private Integer candidateId;
#Id
private Integer jobId;
#Column(name = "reqStatus")
private String reqStatus;
#ManyToOne
#PrimaryKeyJoinColumn(name="candidateId", referencedColumnName="id")
private Candidate candidate;
#ManyToOne
#PrimaryKeyJoinColumn(name="jobId", referencedColumnName="id")
private JobReq jobReq;
public ReqCandAssociation(){
}
Second class
#Entity
#Table(name="comment")
public class Comment {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="commentText")
private String commentText;
#Column(name="commentDate")
private Date commentDate;
#ManyToOne
#PrimaryKeyJoinColumn(name="reqCandAssociationId", referencedColumnName="id")
private ReqCandAssociation reqCandAssociation;
#ManyToOne
#PrimaryKeyJoinColumn(name="userId", referencedColumnName="id")
private User user;
Change this to the following, i'm making it bidirectional mapping.
#Entity
#Table(name = "candidate_jobReq")
public class ReqCandAssociation implements Serializable {
#Id
private Integer candidateId;
#Id
private Integer jobId;
#Column(name = "reqStatus")
private String reqStatus;
#OneToMany(cascade = { CascadeType.ALL }) //this is added here.
#JoinColumn(name ="reqCandAssociationId")
private Set<Comment> comments;
-----
Readup more on the cascade options. All cascade types are all|none|save-update|delete|all-delete-orphan|delete-orphan
The cascade all will delete all the comments associated to this class.

Categories