Hibernate 5 and 6 differences @ManyToOne @JoinColumn

Differences of @ManyToOne @JoinColumn between v5 and v6.

Previously in v5 I had a mapping of:


CatalogHitCountObject
...
@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "partnumber")
	@NotFound(action = NotFoundAction.IGNORE)
	public CatalogueObject getCatalogue() {
		return catalogObject;
	}

Where I did not have the partnumber field on the CatalogHitCountObject pojo.

I had a query that changed the partnumber on mass:

“update CatalogHitCountObject set partnumber=:newPartnumber where partnumber=:partnumber”;

using this :
org.hibernate.query.Query<?> q = getSession().createQuery(query);

When I upgraded to v6 I changed the query statement to use:

org.hibernate.query.MutationQuery q = getSession().createMutationQuery(query);

This did not work as says it cannot find the partnumber field on CatalogHitCountObject, which is correct, it does not exist (and I messed up the query in the conversion).

The only solution I now find to get it working, is to create the partnumber field on the CatalogHitCountObject with the annotation

@Column(name = “partnumber”, insertable = false, updatable = false)

I guess this is the way it now works in v6, or am I missing something?

Cheers

How about this query instead?

update CatalogHitCountObject o
set o.catalogue.partnumber=:newPartnumber 
where o.catalogue.partnumber=:partnumber

or

update CatalogHitCountObject o
set o.catalogue.partnumber=:newPartnumber 
where fk(o.catalogue) =:partnumber

Thanks, but for both examples I get the same error:

Error: 1052-23000: Column ‘partnumber’ in field list is ambiguous

case #1

java.lang.Exception: Records Not Updated : org.hibernate.exception.ConstraintViolationException: JDBC exception executing SQL [update cataloghitcounts chcdo1_0 join catalog cd1_0 on cd1_0.partnumber=chcdo1_0.partnumber set partnumber=? where cd1_0.partnumber=?] [(conn=115) Column ‘partnumber’ in field list is ambiguous] [n/a]

case #2

java.lang.Exception: Records Not Updated : org.hibernate.exception.ConstraintViolationException: JDBC exception executing SQL [update cataloghitcounts chcdo1_0 join catalog cd1_0 on cd1_0.partnumber=chcdo1_0.partnumber set partnumber=? where chcdo1_0.partnumber=?] [(conn=115) Column ‘partnumber’ in field list is ambiguous] [n/a]

I am trying to update the CatalogHitCountObject partnumber
field, not the CatalogueObject partnumber field.

CatalogHitCountObject @Table(name = “cataloghitcounts”)
1 id Primary varchar(48)
2 partnumber Index varchar(48)
3 username Index varchar(255)

CatalogueObject @Table(name = “catalog”)
1 partnumber Primary Index varchar(48)
2 username varchar(255)

This is a bug. Please try to create a reproducer with our test case template and if you are able to reproduce the issue, create a bug ticket in our issue tracker and attach that reproducer.

I have done the test case, with this query (v5 original):

String query = “update HitCount set partNumber=:newPartnumber where partNumber=:partnumber”;

but I get a different error message :

java.lang.IllegalArgumentException: org.hibernate.query.SemanticException: Could not interpret path expression ‘partNumber’

It does create the tables correctly:

Hibernate: 
    create table Catalogue (
        partNumber varchar(255) not null,
        userName varchar(255),
        primary key (partNumber)
    )
Hibernate: 
    create table HitCount (
        id varchar(255) not null,
        partNumber varchar(255),
        userName varchar(255),
        primary key (id)
    )

If I add the partnumber field to HitCount it executes correctly :

@Column(insertable = false, updatable = false)
public String getPartNumber() {
	return partNumber;
}

Is this good enough?

Please post the link to the Jira ticket that you created and make sure that you attach a runnable example application which shows the bug.

issue
https://hibernate.atlassian.net/jira/software/c/projects/HHH/issues/HHH-18766

and producer

Cheers.

1 Like

Well my Jira ticket got closed. I did some more testing and it does work in the producer.

On my system I get this for the query:

query = “update HitCount c set c.catalogue.id=:newPartnumber where c.catalogue.id=:partnumber”;

Hibernate: 
    update
        cataloghitcounts chcdo1_0 
    join
        catalogue cd1_0 
            on cd1_0.partnumber=chcdo1_0.partnumber 
    set
        partnumber=? 
    where
        cd1_0.partnumber=?

[ WARN] (ajp-nio-127.0.0.1-8009-exec-6) Error: 1052-23000: Column ‘partnumber’ in field list is ambiguous

========

The producer for the query:
query = “update HitCount set catalogue.id=:newPartnumber where catalogue.id=:partnumber”;

Hibernate: 
    merge 
    into
        HitCount as t 
    using (
        select
            cast(? as varchar),
            hc1_0._rowid_ from
                HitCount hc1_0 
            join
                Catalogue c1_0 
                    on c1_0.partNumber=hc1_0.partNumber 
            where
                c1_0.partNumber=?
        ) s(c0, c1) 
            on t._rowid_=s.c1 
        when matched 
            then update set
                t.partNumber=s.c0

All the partNumber fields have prefixes?

========

The set on my system seems to missing a prefix?

set
cataloguePartnumber=?

Any ideas?

Cheers

Are you sure you’re using Hibernate ORM 6.6.1? Also, what database version do you use?

Yes hibernate-core-6.6.1.Final.jar. 10.11.6-MariaDB

The fact that the queries are different had me concerned.

The producer is jakarta.persistence.EntityManagerFactory whilst we are using org.hibernate.SessionFactory via spring: org.springframework.orm.hibernate5.LocalSessionFactoryBean.

Reading up, the spring hibernate5 classes should be migrated to JPA style configs but I cannot find much info on how to do this migration.

I would have thought by now this would be a well trodden path.

Sorry, but I can’t help you with Spring questions. You will have to ask that in Spring forums.

Looking more into this (confusing to me, sorry), our app is using hibernate classes to do the work.

All spring does in inject org.hibernate.SessionFactory.

org.hibernate.Session;
org.hibernate.SessionFactory;
org.hibernate.Transaction;
org.hibernate.query.MutationQuery;
org.hibernate.query.NativeQuery;
org.hibernate.query.Query;

Whilst the producer is using

jakarta.persistence.EntityManager;
jakarta.persistence.EntityManagerFactory;
jakarta.persistence.Persistence;
jakarta.persistence.Query;

Guess that is why the query is different. This is a bug on hibernate classes.

Are the hibernate classes deprecated now and we must migrate to jakarta.persistence? What is the point of hibernate then?

The jakarta.persistence package contains just interfaces, Hibernate ORM is the implementation. You can code against these interfaces if you want, since that is more “portable”, but you can also stick to Hibernate ORM classes directly if you prefer and want to leverage Hibernate specific features.

If there a junit producer template anywhere that uses these packages:

org.hibernate.Session;
org.hibernate.SessionFactory;
org.hibernate.query.MutationQuery;
org.hibernate.query.Query;

rather than the “jakarta.persistence” based one in the link, so I can test to see if I have a bug my end?

Cheers Greg

The same repository also contains a test case variant that uses Hibernate ORM types: hibernate-test-case-templates/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/ORMUnitTestCase.java at main · hibernate/hibernate-test-case-templates · GitHub

After some debugging it looks like its todo with the dialect. The ORMUnitTestCase test case uses org.hibernate.dialect.H2Dialect. I am not setting a dialect since HHH90000025, and my junit test uses class MariaDBSqlAstTranslator class to work out the statement. The reason why the sql statements are different.

If I change my junit test to H2Dialect I get the same sql as the producer (but does not work due to the syntax and database mismatch):

Hibernate: 
    merge 
    into
        hitcount as t 
    using (
        select
            cast(? as varchar(255)),
            chcdo1_0._rowid_ from
                hitcount chcdo1_0 
            join
                catalogue cd1_0 
                    on cd1_0.partnumber=chcdo1_0.partnumber 
            where
                cd1_0.partnumber=?
        ) s(c0, c1) 
            on t._rowid_=s.c1 
        when matched 
            then update set
                t.partnumber=s.c0

[main] WARN org.mariadb.jdbc.message.server.ErrorPacket - Error: 1064-42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'merge into hitcount as t using (select cast('TestPartNumberJunit1Rena...' at line 1

If I update the producer to my use my mariadb (rather than org.h2.Driver) I get the same sql statement and error as my junit:

Hibernate: 
    update
        HitCount hc1_0 
    join
        Catalogue c1_0 
            on c1_0.partNumber=hc1_0.partNumber 
    set
        partNumber=? 
    where
        c1_0.partNumber=?
2024-11-21 09:56:12 WARN  SqlExceptionHelper:145 - SQL Error: 1052, SQLState: 23000
2024-11-21 09:56:12 ERROR SqlExceptionHelper:150 - (conn=114) Column 'partNumber' in field list is ambiguous

Luckily I only have one of these pojos so I guess I have to use my work around and add the column.

This is a bug on hibernate not supporting mariadb/mysql and others??

Cheers

Yes this is a bug. Thanks for reporting it. We’ll take care of it as soon as we can.

Please update the reproducer and post a comment on the Jira issue that this is a MariaDB specific issue.

OK thanks. I have updated the producer. Jira is marked as closed, do I need another issue?

Cheers