I'm using Hibernate to model 2 tables joined by a relation table with internal variables like this:
// Clinic.java
@Entity
@Table(name = "clinic")
public class Clinic
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.clinic", cascade = CascadeType.ALL)
private Set<ClinicDoctor> clinicDoctors = new HashSet<ClinicDoctor>(0);
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@JsonIgnore
public Set<ClinicDoctor> getClinicDoctors()
{
return clinicDoctors;
}
public void setClinicDoctors(Set<ClinicDoctor> clinicDoctors)
{
this.clinicDoctors = clinicDoctors;
}
}
// Doctor.java
@Entity
@Table(name = "doctor")
public class Doctor
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name", nullable = false)
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.doctor", cascade = CascadeType.ALL)
private Set<ClinicDoctor> clinicDoctors = new HashSet<ClinicDoctor>(0);
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@JsonIgnore
public Set<ClinicDoctor> getClinicDoctors()
{
return clinicDoctors;
}
public void setClinicDoctors(Set<ClinicDoctor> clinicDoctors)
{
this.clinicDoctors = clinicDoctors;
}
}
// ClinicDoctor
@Entity
@Table(name = "clinic_doctor")
@AssociationOverrides({ @AssociationOverride(name = "pk.clinic", joinColumns = @JoinColumn(name = "clinic")),
@AssociationOverride(name = "pk.doctor", joinColumns = @JoinColumn(name = "doctor")) })
public class ClinicDoctor
{
@EmbeddedId
private ClinicDoctorId pk = new ClinicDoctorId();
@Column(name = "attendingHours")
private String attendingHours;
public ClinicDoctorId getPk()
{
return pk;
}
public void setPk(ClinicDoctorId pk)
{
this.pk = pk;
}
public String getAttendingHours()
{
return attendingHours;
}
public void setAttendingHours(String attendingHours)
{
this.attendingHours = attendingHours;
}
// Equals & HashCode
}
// ClinicDoctorId
public class ClinicDoctorId implements Serializable
{
private static final long serialVersionUID = 5880105185191860784L;
@ManyToOne
private Clinic clinic;
@ManyToOne
private Doctor doctor;
public Clinic getClinic()
{
return clinic;
}
public void setClinic(Clinic clinic)
{
this.clinic = clinic;
}
public Doctor getDoctor()
{
return doctor;
}
public void setDoctor(Doctor doctor)
{
this.doctor = doctor;
}
// Equals & HashCode
}
I want to list all relations where the name of the clinic is 'X'. My best attempt so far is this:
Criteria criteria = session.createCriteria(ClinicDoctor.class);
criteria.createAlias("pk.clinic", "clinic").add(Restrictions.eq("clinic.name", "X"));
res = new ArrayList<>(criteria.list());
This, however, results in the following Hibernate query and error:
Hibernate:
select
this_.clinic as clinic2_1_0_,
this_.doctor as doctor3_1_0_,
this_.attendingHours as attendin1_1_0_
from
clinic_doctor this_
where
clinic1_.name=?
ERROR: Unknown column 'clinic1_.name' in 'where clause'
I honestly have no idea why this is wrong. I believe to have done this before, but somewhere there's something I just can't see (or understand) that prevents this query from working. Can somebody give me a hand with this?
EDIT: As suggested below, I tried this:
Query query = session.createQuery("SELECT cd FROM ClinicDoctor cd WHERE cd.doctor.name = :docname");
query.setParameter("docname", X);
and it works perfectly. However, I'd prefer a Criteria based answer, or at least an explanation as to why my initial query doesn't work. Any ideas?
first thing i see is
where
clinic1_.name=?
while you said in your question :
I want to list all relations where the name of the doctor is 'X'.
so your query is trying to feching relations where the name of the clinic is 'X'
if you wish the first one try this out :
Query query = session.createQuery("SELECT cd FROM ClinicDoctor cd WHERE cd.doctor.name = :docname");
query.setParameter("docname", X);