[Java / EB QL] Gebruik van outer joins

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • smesjz
  • Registratie: Juli 2002
  • Niet online
Ik ben sinds een tijdje aan het werken met EB QL met Java EE 6 / JSF 2.0 in Netbeans 6.8. Hiervoor wordt ook JPA 2.0 via EclipseLink gebruikt en dit werkt goed op 1 probleem na.

In SQL kan ik nu het volgende doen:
SQL:
1
SELECT t.*,g.global_id FROM taak t LEFT OUTER JOIN global g ON g.taak_id=t.taak_id AND gebruiker_id=2 WHERE g.revoked is NULL;


Deze selecteert de taken van een specifieke gebruiker. Indien g.global_id gelijk is aan null heeft de medewerker de specifieke taak niet. Precies wat volstaat.

Nu de vertaalslag naar EJB's:
Java:
1
2
3
4
5
6
7
8
9
10
11
@Entity
 public class Global implements Serializable {

*knip*
    @JoinColumn(name = "gebruiker_id", referencedColumnName = "gebruiker_id")
    @ManyToOne
    private Gebruiker gebruikerId;

    @JoinColumn(name = "taak_id", referencedColumnName = "taak_id")
    @ManyToOne
    private Taak taakId;



Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Taak implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
        @SequenceGenerator(name = "taak_gen", sequenceName="taak_seq", initialValue=0, allocationSize=1)
    @GeneratedValue(generator="taak_gen",strategy=GenerationType.SEQUENCE)
    @Column(name = "taak_id")
    private Integer taakId;
    @Column(name = "taaknaam")
    private String taaknaam;
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "taakId")
    private Collection<Global> globalCollection;
   
    public Collection<Global> getGlobalCollection() {
        return globalCollection;
    }

    public void setGlobalCollection(Collection<Global> globalCollection) {
        this.globalCollection = globalCollection;
    }
  


Onderstaande query werkt niet geeft een foutmelding:

code:
1
2
Exception Description: Syntax error parsing the query [SELECT t.taaknaam FROM Taak t LEFT OUTER JOIN t.globalCollection tgc AND tgc.gebruikerId=:gebruiker WHERE t.cianonly=0], line 1, column 69: syntax error at [AND].
Internal Exception: MismatchedTokenException(6!=-1)


Onderstaande query werkt wel, maar daar werkt de left outer join als een inner join. Ik krijg dus maar 2 records terug (taak komt zowel voor in Taak als Global voor betreffende medewerker) i.p.v. de 10 via SQL.

code:
1
2
Query query = em.createQuery("SELECT t,tgc FROM Taak t LEFT OUTER JOIN t.globalCollection tgc WHERE tgc.gebruikerId=:gebruiker AND t.cianonly=0");
        query.setParameter("gebruiker", g);



Ik krijg het niet voor elkaar om de vertaalslag te maken naar Java voor deze relatie. Ongetwijfeld doe ik iets fout, maar ik zie het niet (meer). Zou iemand mij in de goede richting kunnen duwen?

[ Voor 0% gewijzigd door smesjz op 22-01-2010 14:55 . Reden: Code tag fixes voor Java & SQL ]


Acties:
  • 0 Henk 'm!

  • momania
  • Registratie: Mei 2000
  • Nu online

momania

iPhone 30! Bam!

SQL:
1
SELECT t, tgc FROM Taak t LEFT OUTER JOIN t.globalCollection tgc WHERE tgc.gebruikerId=:gebruiker AND t.cianonly =0


Bedoel je niet: t.tgc :? (Met een punt dus)

De error lijkt trouwens wel van een totaal andere query :?

SQL:
1
SELECT t.taaknaam FROM Taak t LEFT OUTER JOIN t.globalCollection tgc AND tgc.gebruikerId=:gebruiker WHERE t.cianonly=0

[ Voor 36% gewijzigd door momania op 22-01-2010 15:46 ]

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Je hebt eigenlijk een ManyToMany relatie tussen een Taak en een Gebruiker.
Dat kan je dan ook mappen zonder een entiteit voor Global te definieren:
Java:
1
2
3
4
5
@ManyToMany
    @JoinTable(name="GLOBAL",
        joinColumns=@JoinColumn(name="TAAK_ID", referencedColumnName="TAAK_ID"),
        inverseJoinColumns=@JoinColumn(name="GEBRUIKER_ID", referencedColumnName="GEBRUIKER_ID")
        )

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • smesjz
  • Registratie: Juli 2002
  • Niet online
momania schreef op vrijdag 22 januari 2010 @ 15:45:
SQL:
1
SELECT t, tgc FROM Taak t LEFT OUTER JOIN t.globalCollection tgc WHERE tgc.gebruikerId=:gebruiker AND t.cianonly =0


Bedoel je niet: t.tgc :? (Met een punt dus)
Klopt. Bij het copy/pasten/aanpassen van de query voor dit topic is dat idd niet goed gegaan. Die 'tgc' hoort daar overigens niet. My bad.
De error lijkt trouwens wel van een totaal andere query :?

SQL:
1
SELECT t.taaknaam FROM Taak t LEFT OUTER JOIN t.globalCollection tgc AND tgc.gebruikerId=:gebruiker WHERE t.cianonly=0
De parser vindt blijkbaar de 'AND' in "LEFT OUTER JOIN t.globalCollection tgc AND tgc.gebruikerId=:gebruiker" niet goed. Het gebruik van 'AND' op die manier is wel geldige SQL maar blijkbaar geen geen geldige EJB QL.

Als ik die 'AND' vervang door WHERE krijg ik geen fout maar niet de records die ik wil.

Acties:
  • 0 Henk 'm!

  • smesjz
  • Registratie: Juli 2002
  • Niet online
Macros schreef op vrijdag 22 januari 2010 @ 15:56:
Je hebt eigenlijk een ManyToMany relatie tussen een Taak en een Gebruiker.
Dat kan je dan ook mappen zonder een entiteit voor Global te definieren:
Java:
1
2
3
4
5
@ManyToMany
    @JoinTable(name="GLOBAL",
        joinColumns=@JoinColumn(name="TAAK_ID", referencedColumnName="TAAK_ID"),
        inverseJoinColumns=@JoinColumn(name="GEBRUIKER_ID", referencedColumnName="GEBRUIKER_ID")
        )
Interessant, deze notatie kende ik nog niet. Deze dien ik dus op te nemen bij de Taak.class?

Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Voordat je de ManyToMany annotatie gaat gebruiken (ipv. de OneToMany and ManyToOne) zou ik even de documentatie lezen: bijv.: http://java.sun.com/javae...rsistence/ManyToMany.html en boeken en wat je nu al hebt gebruikt.

Inderdaad, de EJB QL ondersteund niet de normale JOIN syntax zoals je gewend bent in SQL. In SQL specificieer je waarop je joined, in EJB QL zeg je alleen welke property je erbij joined, en wat hij dan joined is afhankelijk van hoe die property is gespecificeerd.

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • B-Man
  • Registratie: Februari 2000
  • Niet online
smesjz schreef op vrijdag 22 januari 2010 @ 16:00:
[...]De parser vindt blijkbaar de 'AND' in "LEFT OUTER JOIN t.globalCollection tgc AND tgc.gebruikerId=:gebruiker" niet goed. Het gebruik van 'AND' op die manier is wel geldige SQL maar blijkbaar geen geen geldige EJB QL.

Als ik die 'AND' vervang door WHERE krijg ik geen fout maar niet de records die ik wil.
Uhm, als je even goed kijkt zie je dat je SQL verschilt van je EJBQL. In SQL kun je ook niet zeggen: LEFT OUTER JOIN (tabelnaam) AND (conditie). In je SQL query staan direct na de JOIN dan ook 2 condities, als je in SQL de eerste daarvan weg zou halen komt de AND ook te vervallen :)

Verder, zoals reeds gezegd is, kun je deze relatie beter via ManyToMany mappen.

Inhoudelijk was ik je al bij je eerste alinea kwijt. Je toont namelijk een query die alle taken van een gebruiker joined, en vervolgens zeg je daarna "... heeft de medewerker de specifieke taak niet".
Een left join is prima te maken met EBQL / HQL en consorten, dus je vraagstuk is zeker op te lossen.

Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
[b][message=33329364,noline]
Inderdaad, de EJB QL ondersteund niet de normale JOIN syntax zoals je gewend bent in SQL. In SQL specificieer je waarop je joined, in EJB QL zeg je alleen welke property je erbij joined, en wat hij dan joined is afhankelijk van hoe die property is gespecificeerd.
't is een beetje oude post, maar om het toch even recht te zetten: het is niet EJB QL maar JPQL ;) Die eerste benaming is nogal oud en wordt al een poosje niet meer gebruikt, zeker niet meer in Java EE 6 waar JPA volledig los getrokken is van EJB. In Java EE 5 was JPA eigenlijk ook al vrij los, maar was het wel een sub specificatie van EJB3.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.

Pagina: 1