-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Native query with joined many-to-many association
PostPosted: Mon Apr 03, 2017 5:21 pm 
Newbie

Joined: Mon Apr 03, 2017 5:08 am
Posts: 1
Hello,

I’m not used to ask for help but I’m really stuck for a few days. No way to find the same issue on Stackoverflow or Google...

I have two entities Event and Artist with a many-to-many relationship. The join table is EventArtists.
Code:
Event <-- EventArtists --> Artist

Artist
Code:
@Entity
public class Artist {
@Id
@GeneratedValue
private Long idArtist;
private String name;
private String description;
@ManyToMany(mappedBy = "artists")
private Set<Event> events = new HashSet<Event>();

Event
Code:
@Entity
public class Event {
@Id
@GeneratedValue
private Long idEvent;
private String name;
private String description;
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinTable(name="EventArtists",
        joinColumns=
        @JoinColumn(name="idEvent"),
        inverseJoinColumns=
        @JoinColumn(name="idArtist")
)
private Set<Artist> artists = new HashSet<Artist>();


I’m trying to fetch an event and its associated artists using a native query. According to the documentation, I’m using addEntity and addJoin. Since the two entities are mapped to the same column names (id, name, description), I also use aliases.

Here is my request:
Code:
NativeQuery nativeQuery = session.createNativeQuery("SELECT {e.*}, {a.*} "+
      "FROM Event e "+
      "LEFT JOIN EventArtists ea ON e.idEvent = ea.idEvent "+
      "LEFT JOIN Artist a ON a.idArtist = ea.idArtist "+
      "WHERE e.idEvent = :id");
nativeQuery.addEntity("e", Event.class)
         .addJoin("a", "e.artists")
         .setParameter("id", 1);
nativeQuery.getResultList();

nativeQuery.getResultList() throws the following exception :
Quote:
org.h2.jdbc.JdbcSQLException: Column "A.IDEVENT" not found

Indeed, Hibernate doesn’t generate correctly the request. It looks for columns "a.idEvent as idEvent1_2_0__, a.idArtist as idArtist2_2_0__", which are EventArtists's columns.
We get:
Quote:
SELECT e.idEvent as idEvent1_1_0_, e.description as descript2_1_0_, e.name as name3_1_0_, a.idEvent as idEvent1_2_0__, a.idArtist as idArtist2_2_0__, a.idArtist as idArtist1_0_1_, a.description as descript2_0_1_, a.name as name3_0_1_ FROM Event e LEFT JOIN EventArtists ea ON e.idEvent = ea.idEvent LEFT JOIN Artist a ON a.idArtist = ea.idArtist WHERE e.idEvent = ?

instead of
Quote:
SELECT e.idEvent as idEvent1_1_0_, e.description as descript2_1_0_, e.name as name3_1_0_, a.idArtist as idArtist1_0_1_, a.description as descript2_0_1_, a.name as name3_0_1_ FROM Event e LEFT JOIN EventArtists ea ON e.idEvent = ea.idEvent LEFT JOIN Artist a ON a.idArtist = ea.idArtist WHERE e.idEvent = ?


  • Here is a complete TestCase: https://github.com/volvotrax/hibernate/
  • The HQL query works perfectly but I need to use a native query since the where clause is much more complicated and relies on a database functionality.
    Code:
    "FROM Event e LEFT JOIN FETCH e.artists WHERE e.idEvent = :id"

  • Renaming column names to avoid using aliases is a solution but it’s not possible.
  • I'm using Hibernate 5.2

Your assistance will be very much appreciated.
Thank you


Top
 Profile  
 
 Post subject: Re: Native query with joined many-to-many association
PostPosted: Tue Apr 04, 2017 3:43 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Most likely it's a bug, but you don't need to use the aliases to get the desired result. There also another bug for one-to-many as well.

If you use addEntity for Tag instead of addJoin, you'll get an Object[] tuple result. You should write a replicating test case and open a Jira issue for it.

If you really need to select entities, then the workaround goes like this:

1. Write the native query to select the ids of the Company you'd like to fetch
2. Then using the Company ids, use a JPQL query to fetch the Companies along with all their Departments by the given Company ids

However, it might be that you don't even need entities. Remember that entities are only useful if you plan to modify them. Otherwise, a DTO projection is a much more efficient alternative.

If you need to use a DTO, then just use a ResultTransformer to map the DepartementDTO to its parent CompanyDTO. Check out this article for an example of how ResultTransformer works.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.