Reputation: 937
maybe duplicate question but I couldn't fina a solution for my case which I think is pretty simple.
I have two tables like so :
And those are the related DTO Object :
First table
@Entity
@Table(name = "DA10003_REF_SIGNALEMENT")
public class RefSignalement {
@Id
@Column(name = "CD_SIGNALEMENT")
public String codeSignalement;
@Column(name = "LIBELLE")
public String libelle;
@Column(name = "CATEGORIE")
public String categorie;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "CD_SIGNALEMENT")
public List<RefMessage> refMessages;
}
Second table :
@Entity
@Table(name = "DA10004_REF_MESSAGE")
public class RefMessage {
@Id
@Column(name = "CD_SIGNALEMENT")
public String codeSignalement;
@Id
@Column(name = "DESTINATAIRE")
public String destinataires;
@Column(name = "MESSAGE")
public String message;
}
And the following query to get all the RefSignelement
with the associated message :
List<RefSignalement> listRefSignalement = em.createQuery("SELECT p FROM RefSignalement p, RefMessage m", RefSignalement.class).getResultList();
Unfortunately it's returning an empty list, I have tried to change it with join fetch
but nothing change.
Thank for the help
Upvotes: 1
Views: 1574
Reputation: 3753
Remember that in JPQL you have to think in Objects, not relations. You want to fetch all 'RefSignalement' and eagerly fetch their 'refMessages' properties:
SELECT DISTINCT s FROM RefSignalement s JOIN FETCH s.refMessages
Here the "distinct" is only needed by JPA when assembling your resulting entities, but add unnecessary overhead to the SQL Query. If you have a Hibernate version >= 5.2.2 (I think), then there is a query hint you can use to avoid that:
List<RefSignalement> sigs = entityManager
.createQuery(
"select distinct s " +
"from RefSignalement s " +
"left join fetch s.refMessages ")
.setHint("hibernate.query.passDistinctThrough", false)
.getResultList();
Read more about it here.
Upvotes: 1
Reputation: 458
a couple of things, RefMessage
class is using composite primary key so i guess you need to use @IdClass
or @EmbeddedId
annotation. here I'm providing using
@IdClass
public class RefId implements Serializable {
private String codeSignalement;
private String destinataires;
// default constructor
public RefId() {
}
public RefId(String codeSignalement, String destinataires) {
this.codeSignalement = codeSignalement;
this.destinataires = destinataires;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RefId refId = (RefId) o;
return Objects.equals(codeSignalement, refId.codeSignalement) &&
Objects.equals(destinataires, refId.destinataires);
}
@Override
public int hashCode() {
return Objects.hash(codeSignalement, destinataires);
}
}
then you need to use like follows
@Entity
@Table(name = "DA10004_REF_MESSAGE")
@IdClass(RefId.class)
public class RefMessage {
@Id
@Column(name = "CD_SIGNALEMENT")
public String codeSignalement;
@Id
@Column(name = "DESTINATAIRE")
public String destinataires;
@Column(name = "MESSAGE")
public String message;
}
define your repository as follows:
public interface RefSignalementRepo extends
JpaRepository<RefSignalement, String> {
}
RefSignalement
class defination as follows:
@Entity
@Table(name = "DA10003_REF_SIGNALEMENT")
public class RefSignalement {
@Id
@Column(name = "CD_SIGNALEMENT")
public String codeSignalement;
@Column(name = "LIBELLE")
public String libelle;
@Column(name = "CATEGORIE")
public String categorie;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinColumn(name = "CD_SIGNALEMENT")
public List<RefMessage> refMessages;
}
very example app
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(App.class, args);
RefSignalementRepo repo = context.getBean(RefSignalementRepo.class);
RefSignalement obj = new RefSignalement();
obj.codeSignalement = "1";
obj = repo.save(obj);
obj.refMessages = new ArrayList<>();
RefMessage message = new RefMessage();
message.codeSignalement = "1";
message.destinataires = "2";
message.message = "custom message";
obj.refMessages.add(message);
obj = repo.save(obj);
List<RefSignalement> objs = repo.findAll();
System.out.println(objs.get(0).refMessages.size());
EntityManager em = context.getBean(EntityManager.class);
List<RefSignalement> listRefSignalement = em.createQuery("SELECT p FROM RefSignalement p, RefMessage m", RefSignalement.class).getResultList();
System.out.println(listRefSignalement.get(0).refMessages.size());
}
}
Upvotes: 1