#SQL Hibernate JPA

258 messages · Page 1 of 1 (latest)

stone pulsar
#

I'm having a bit of a problem, I am trying to gather adresses with the same date from my database.
I have the following code:

try {
            String queryString = "SELECT a FROM Adres a JOIN Order o ON a.klantID = o.klantID WHERE o.orderDatum = :orderDatumParam";

            Query query = session.createQuery(queryString);
            query.setParameter("orderDatumParam", dateTime);
            adressen = (ArrayList<Adres>) query.getResultList();
        }

Now I get the following error:
java.lang.IllegalArgumentException: org.hibernate.query.sqm.InterpretationException: Error interpreting query [SELECT a FROM Adres a JOIN Order o ON a.klantID = o.klantID WHERE o.orderDatum = :orderDatumParam]; this may indicate a semantic (user query) problem or a bug in the parser [SELECT a FROM Adres a JOIN Order o ON a.klantID = o.klantID WHERE o.orderDatum = :orderDatumParam]
I can't figure out for the life of me, how to make this work.

eternal copperBOT
#

This post has been reserved for your question.

Hey @stone pulsar! Please use /close or the Close Post button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

stone pulsar
#

orderDatumParam is being supplied by the method

eternal copperBOT
#

<@&765578700724371486>

Requested by Rowin ツ#2022
gritty delta
#

I am not an sql expert but shouldnt it be something like
SELECT a.columnName FROM Adres a
maybe it cannot differentiate the a's otherwise?

stone pulsar
#

Ive tried that too,

#

though I have found there was another problem that might be underlining this

#

Could not resolve entity reference : Order

#

Though I have literally checked everything inside my database and my persistance entity

gritty delta
#

shouldnt it be JOIN Orders

stone pulsar
#

It works with Klant and Adres when I simply use just the single

gritty delta
#

Did you connect the ide to your db so it can resolve this?

stone pulsar
#

I have

#

screenshot from the database table is from inside the db

#
            adressen = (ArrayList<Adres>) session.createQuery("SELECT a FROM Adres a").getResultList();
#

This is for example a query to simply get all the adresses

#

Which works perfectly fine

#

But once I'm trying to compare other values with different tables and columns I cant get it to work.

#

Ive had some fair amount of experience with SQL with C# and Linq

#

But in Java i just, cant lol

gritty delta
#

I see, then it might be a plain sql query syntax problem, I am not good at those 😄

stone pulsar
#

Bummer,

#

well thanks for trying anyway.

eternal copperBOT
# stone pulsar well thanks for trying anyway.

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

stone pulsar
#

Hopefully someone else does

gritty delta
#

but if you have JPA Repositories you could just do something similar just with the repo methods, no?

stone pulsar
#

Im not sure what you mean exactly

gritty delta
#

ok, give me a minute

#

What parameters do you use for the search? Date and klantID?

#

or do you want to get all adresses that have a order date in common?

stone pulsar
#

Correct

#

the latter

gritty delta
#

So the date is a param from what I see that you provide?

stone pulsar
#

Yes

gritty delta
#

in JPA Repos you can define your own methods like
findById - this one is default

But JPA lets you define your own in an interface that extends from the JPA Repo
then you could do something like

Adress findByDate(Date date)
for this to work there has to be a field named date or what ever in Adress

#

Do you get the idea?

gritty delta
#

yeah, does this not work for you?

stone pulsar
#

Im honestly not sure if im in Spring

#

Ive created a project with just Hibernate and JPA

fossil inlet
#

Just use the JPA repository finaction as so
findOneByOrderId

#

Oh we're in just Hibernate and JPA

#

Thats... a bigger issue

stone pulsar
#

Could I somehow just add the Spring package?

#

Or would this cause too much problems

gritty delta
#

hmm not sure

fossil inlet
#

Would cause too many problems

stone pulsar
#

Bummer

fossil inlet
#

Have you tried using Select * instead of Select a?

stone pulsar
fossil inlet
#

Hmm

stone pulsar
#

The docs on JPA and Hibernate didnt imply I also had to use Spring

#

afaik

fossil inlet
#

You don't, it's just the most common way people get Hibernate into their projects

stone pulsar
#

I see

#

Though as I mentioned before,

#

it might also be a problem regarding the Order entity

fossil inlet
#

Yeah you need to define an association between the entities

stone pulsar
#
@Table(name = "Orders")
@Entity
public class Order {
    @Id
    private int orderID;
    @ManyToOne
    @JoinColumn(name = "klantID")
    private Klant klant;
    private Date orderDatum;
    private Date afleverDatum;
    private int isAfgeleverd;

}
#

This is what I got now

fossil inlet
#

That should work, what happens if you try and run the query?

stone pulsar
#

with these changes i got this in my query

fossil inlet
#

Yep, you no longer need to define the on portion of the Join IIRC

#

The entity defines the join criteria itself.

gritty delta
#

just klant should be used now, no?

stone pulsar
#
            String queryString = "SELECT a FROM Adres a JOIN Order o ON Klant = Klant WHERE o.orderDatum = :orderDatumParam";
#

Like this?

fossil inlet
#

Just remove the ON portion

#

So SELECT a FROM Adres a JOIN Order o WHERE o.orderDatam = :orderDatumParam

stone pulsar
#

still seems to have problems with Order too

fossil inlet
#

What does Adres look like?

stone pulsar
#

Ah wait

fossil inlet
#

In general you should avoid thinking about your Entities in Terms of SQL. They are the abstraction layer for it. Likewise our Query string isn't actually Raw SQL, but a HSQL String. So we're trying to navigate the relationship from the Object side

#

I mean the Adres.java

stone pulsar
#

yeah I believe i still have to add the Foreign key stuff there as well

fossil inlet
#

Yep

stone pulsar
#

Though its weird because I can just grab the Adres alone

#

Or does it not care about the keys in that instance

fossil inlet
#

Relationships in Hibernate are directional, so if you define a relationship on Order pointing to Adres, that doesn't mean you can instantly go from Adres to Order

#

Likewise Hibernate doesn't check the Database Schema (normally) so it doesn't see that Adres has a FK to Order (Assuming it does)

stone pulsar
#

I see,

#

well this is a bit of unfortunate timing, but I still have some errors and Ive got to eat dinner.

#

So I'll be back in a few minutes im sorry

fossil inlet
#

No worries, I'll be back in 45 minutes myself, since I have a 1:1 meeting in 15

stone pulsar
#

Then it might be perfect timing 😅

stone pulsar
#

i am back

fossil inlet
#

I am not

stone pulsar
#

The errors remain the same as the ones before

fossil inlet
#

Did you add the Relationship in the Address

stone pulsar
#
@Entity
@Table(name = "Adressen")
public class Adres {
    @Id
    private int adresID;
    @ManyToOne
    @JoinColumn(name = "klantID")
    private Klant klant;
    private String postcode;
    private String straatnaam;
    private String huisnummer;
    private String plaats;
    private String routeID;
fossil inlet
#

And our Query String?

stone pulsar
#
            String queryString = "SELECT a FROM Adres a JOIN Order o WHERE o.orderDatum = :orderDatumParam";
fossil inlet
#

And the exception?

stone pulsar
#

Error interpreting query [SELECT a FROM Adres a JOIN Order o WHERE o.orderDatum = :orderDatumParam];

#

Could not resolve entity reference : Order

fossil inlet
#

Yes, Address doesn't have a reference to the Order

#

So you need to add that relationship

#

Or maybe, what does Klant look like?

stone pulsar
#
@Entity
@Table(name = "Klanten")
public class Klant {
    @Id
    private int klantID;
    private String voornaam;
    private String achternaam;
    private String tussenvoegsel;
}
fossil inlet
#

And so Adres really related to Order by going through Klant right?

stone pulsar
#

Order is the connection between Adres and Klant

#

Adres will alway have a klant

#

but not always have a Order

#

Ill see if i can find our ERD real quick

fossil inlet
#

So Klant is missing a relationship to Order and Address in its entity

#

Are you using IntelliJ Ultimate?

stone pulsar
#

Its not fully up-to-date I just realised

stone pulsar
fossil inlet
#

So we need to define the relationship of both in the Klant class as well

stone pulsar
#

Is there something that ignores the actual relationship inside the DB for that? I know in EF C# there is such thing

#

I cant quite change the structure of the database

#

at least, not now.

#

Cant quite put my finger on what it was called again

fossil inlet
#

Don't need to edit the database

stone pulsar
#

Alright,

#

How would I go about that 😅

#

Head is in a bit of a twist now

fossil inlet
#

With the Many-To-One, One-To-One, One-To-Many annotations

stone pulsar
#

but both adres and order already have a relationship to klant no?

fossil inlet
#

But Klant doesn't

stone pulsar
#

Wont that mess up with the Entity if I'd add more variables?

fossil inlet
#

Nope

#

As long as it's accurate

#
   String queryString = "SELECT a FROM Adres a JOIN Klant k JOIN Order o WHERE o.orderDatum = :orderDatumParam"

Since we're really doing

order.getKlant().getAdres()

After the SQL gets the Order

stone pulsar
#

Ive done a bit of googline

#

but I dont think this is it

#
    @ManyToMany
    @JoinTable(
            name = "Klant_Adres",
            joinColumns = @JoinColumn(name = "klantID"),
            inverseJoinColumns = @JoinColumn(name = "adresID")
    )
    private ArrayList<Adres> adressen;
    @ManyToMany
    @JoinTable(
            name = "Klant_Order",
            joinColumns = @JoinColumn(name = "klantID"),
            inverseJoinColumns = @JoinColumn(name = "orderID")
    )
    private ArrayList<Order> orders;
fossil inlet
#

Since you put ManyToOne on your Order/Adres, I'd assume Klant has a OneToMany to Order/Adres

#

Meaning one Klant has many orders, and many addresses

stone pulsar
#

Klant only has an ID

#
@Entity
@Table(name = "Klanten")
public class Klant {
    @Id
    private int klantID;
    private String voornaam;
    private String achternaam;
    private String tussenvoegsel;
}

fossil inlet
#

Think of the Join Table between Klant and Order, what does it look like?

klantID | orderID
1       | 2          // 1:1 if one and two cannot appear any more

1       | 3
1       | 4          // 1 to Many from Klant's Perspective

1       | 2
3       | 2          // Many to One from Klant's Perspective

1       | 2
1       | 3
2       | 3           // Many to Many
stone pulsar
#

hmh

fossil inlet
#

If you're going to use an ORM, it's also good to think about Data Modeling in terms of the Java Code.

If Order only can link to one Klant, and one Klant can link to a List of Orders, then @OneToMany on Klant, and @ManyToOne on Orders is correct.

stone pulsar
#

A Klant can have multiple orderes but one adres

fossil inlet
#

And Adres can only have one Klant? If so then it's a One to One for both of them

stone pulsar
#

Yes

#

but there can be multiple orders on one adres

#

if that makes sense

fossil inlet
#

Does Adres have a FK to Orders? Or is that through the FK to Klant with has the relationship to Orders?

stone pulsar
#

different order, same adres, different delivery date

#

The latter

fossil inlet
#

I'll remove some fields, but this is roughly what you want then.

// Adres.java
@Entity
@Table("adres)
class Adres {
   @Id
   private int adresId;
   @OneToOne(column = "klantID")
   private Klant klant;
}
// Klant.java
@Entity
@Table("klant")
class Klant {
   @Id
   private int klantId;
   @OneToOne(column = "klantID")
   private Adres adres;
   @OneToMany
   private List<Order> orders; // Use List in this context!!!
}
// Order.java
@Entity
@Table("order")
class Order {
   @Id
   private int orderId;
   @ManyToOne
   @JoinColumn(name = "klantID")
   private Klant klant
}

With the query String being

String queryString = "SELECT a FROM Adres a JOIN Klant k JOIN Order o WHERE o.orderDatum = :orderDatumParam"
#

Regarding the note about List, in general when dealing with Abstractions in Java, you want to return the lowest abstraction you care about, especially in a context where a library is doing lifting, we choose List instead of Collection in this context, just for clarity in that we're dealing with a List, likewise you could also say Set if you wanted the Java code to ensure uniqueness.

stone pulsar
#

That OneToOne line doesnt seem to be recognized

#
   @OneToOne(column = "klantID")
fossil inlet
#

Column name might be wrong, or not required, not entirely positive

#

The main thing was getting the relationships right.

stone pulsar
#

It doesnt seem to have a problem with it being empty

#

Well theres still an error

#

but a different one

#

so thats a start

fossil inlet
#

Ooo

stone pulsar
#

Use of @OneToMany or @ManyToMany targeting an unmapped class: Klant.orders[Order]

fossil inlet
#

Did you put the JoinColumn in Order?

stone pulsar
#

that one was already there

#

Ive put it like youve shown

fossil inlet
#

@OneToMany(mappedBy="klant") swap the One to Many in Klant for that

stone pulsar
#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.klantID

#

oh wait

#

I forgot to change the query

#

holdon

#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.klantID

#

still

fossil inlet
#

Is the column name correct?

stone pulsar
#

in Klant?

fossil inlet
#

Yes

#

Or is there additional connections that need to be made first?

stone pulsar
#
    @OneToMany(mappedBy="klantID")
    private ArrayList<Order> orders;
fossil inlet
#

Swap to List<Order>

#

And in the Database are there additional tables we need to traverse?

stone pulsar
#

These are the only 3 tables

fossil inlet
#

This table doesn't exist?

stone pulsar
#

Thats Adressen

#

as I mentioned before, its not fully up to date

#

😅

#

Adressen holds Adres

#

Orders hold Order

#

Klanten holds Klant

fossil inlet
#

What are the Columns for Klant and Adres again? Can you screenshot them?

stone pulsar
#
  1. Adres
  2. Klant
fossil inlet
#

Swap to @OneToOne(mappedBy = "adres") in Klant

#

Try that

stone pulsar
#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.klantIDD

#

oh wait

#

Changed the wrong one sorry

#
@Entity
@Table(name = "Klanten")
public class Klant {
    @Id
    private int klantID;
    @OneToOne(mappedBy = "adres")
    private Adres adres;
    @OneToMany(mappedBy="klantID")
    private List<Order> orders;
    private String voornaam;
    private String achternaam;
    private String tussenvoegsel;
}
#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.adres

fossil inlet
#

@OneToMany(mappedBy="klantID") should be @OneToMany(mappedBy="order")

#

Or wait

#

Maybe it's id?

#

It's probably just whatever you're calling the id column of the object.

stone pulsar
#

Ill try that because it gave the same error

fossil inlet
#

Mapping the relationships are really brutal in ORMs, but normally you do it once, and then don't touch it again.

stone pulsar
#

Referenced property not a (One|Many)ToOne: Adres.adresID in mappedBy of Klant.adres

fossil inlet
#

Swap back to klantID? It should be the name of the FK column

#

Sorry it's even harder when I don't have the schema in front of me kekw

stone pulsar
#

Yeah no i understand lol

#

which one do you mean again

#

the OneToMany?

fossil inlet
#

On both probably

#

And what is the current Query String?

stone pulsar
#
public class Klant {
    @Id
    private int klantID;
    @OneToOne(mappedBy = "klantID")
    private Adres adres;
    @OneToMany(mappedBy= "klantID")
    private List<Order> orders;
    private String voornaam;
    private String achternaam;
    private String tussenvoegsel;
}
#
            String queryString = "SELECT a FROM Adres a JOIN Klant k JOIN Order o WHERE o.orderDatum = :orderDatumParam";
fossil inlet
#

Looks good to me

#

Still getting that exception?

stone pulsar
#

yup

#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.klantID

fossil inlet
#
// Adres.java
@Entity
@Table("adres)
class Adres {
   @Id
   private int adresId;
   @OneToOne
   @JoinColumn(name = "klantID")
   private Klant klant;
}

Maybe that?

stone pulsar
#

Sadly no

#

Im really sorry im putting you through this 😅

fossil inlet
#

No worries.

#
public class Klant {
    @Id
    private int klantID;
    @OneToOne(mappedBy = "klant")
    private Adres adres;
    @OneToMany(mappedBy= "klantID")
    private List<Order> orders;
    private String voornaam;
    private String achternaam;
    private String tussenvoegsel;
}

Tack on that as well maybe?

stone pulsar
#

Use of @OneToMany or @ManyToMany targeting an unmapped class: Klant.orders[Order]

fossil inlet
#
    @OneToMany(mappedBy= "klant")
    private List<Order> orders;

In Adres maybe?

stone pulsar
#

same one

fossil inlet
#

Honestly I'm stumped. Do some more googling, read some docs. I'm sorry d:

stone pulsar
#

Ill do some googling, thanks anyway!

eternal copperBOT
# stone pulsar Ill do some googling, thanks anyway!

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

stone pulsar
#

Oh,my,lord

#

Im just stupid

#

Though its not fully fixed

#
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration()
                    .configure()
                    .addAnnotatedClass(Klant.class)
                    .addAnnotatedClass(Adres.class)
                    .addAnnotatedClass(Order.class)
                    .buildSessionFactory();
        }
        catch (Throwable ex) {
            System.err.println("Failed to create sessionFactory object: " + ex);
            throw new ExceptionInInitializerError(ex);
        }
#

I never added Order.class.....

#

Now, sadly that wasnt everything

#

Unable to determine TableReference (Klanten) for Order.klant.adres.orders.{fk-target}

fossil inlet
#

Is your table on Klant.java Correct?

#

Also yeah I never would have seen this, since Spring does all this configuration for you. So good catch

stone pulsar
#

I remembered something from my EF adventures, this usally had a context builder which is roughly the same as this sessionFactory

#

Buy yeah Klant seems fine

#

Changing the OneToMany and OneToOne to klantID gives back a familiar error again

#

Unknown mappedBy in: Klant.adres, referenced property unknown: Adres.klantID

fossil inlet
#

I mean the @Table annotation on Klant

stone pulsar
#

Yup

fossil inlet
#

Well, more fiddling required

stone pulsar
#

Sadly

fossil inlet
#

Try tossing some @JoinColumn in different places

eternal copperBOT
#

💤 Post marked as dormant

This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.

stone pulsar
#

Well

#

I think ive managed the relatioships

#

but now i am at this point:
jakarta.persistence.PersistenceException: Converting org.hibernate.exception.SQLGrammarException to JPA PersistenceException : JDBC exception executing SQL [select k1_0.klantID,k1_0.achternaam,a1_0.adresID,a1_0.huisnummer,k2_0.klantID,k2_0.achternaam,k2_0.adresID,k2_0.tussenvoegsel,k2_0.voornaam,a1_0.plaats,a1_0.postcode,a1_0.routeID,a1_0.straatnaam,k1_0.tussenvoegsel,k1_0.voornaam from Klanten k1_0 left join Adressen a1_0 on a1_0.adresID=k1_0.adresID left join Klanten k2_0 on k2_0.klantID=a1_0.klantID where k1_0.klantID=?] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:165) at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:374) at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:986) at org.hibernate.query.Query.getResultList(Query.java:94)

fossil inlet
stone pulsar
#

I’ll try that