[JIRA] (HHH-16489) Hibernate native query returns duplicate column values with addScalar() call
by Prithvi singh (JIRA)
Prithvi singh ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=712020%... ) *commented* on HHH-16489 ( https://hibernate.atlassian.net/browse/HHH-16489?atlOrigin=eyJpIjoiNjY4M2... )
Re: Hibernate native query returns duplicate column values with addScalar() call ( https://hibernate.atlassian.net/browse/HHH-16489?atlOrigin=eyJpIjoiNjY4M2... )
Hi @Puhong You, I tried to look into this issue and executed the above mentioned test case in version 5.6.15. Unfortunately, the test is not completing and I am getting org.hibernate.MappingException as java.lang.Integer class could not be recognised as an entity.
Here are the attached snippets. I am using maven as my build tool and h2 as my database.
My pom.xml
<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion> 4.0.0 </modelVersion>
<groupId> org.example </groupId>
<artifactId> hibernate-tests </artifactId>
<version> 1.0-SNAPSHOT </version>
<packaging> jar </packaging>
<name> hibernate-tests </name>
<url> http://maven.apache.org </url>
<properties>
<project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding>
<maven.compiler.source> 17 </maven.compiler.source>
<maven.compiler.target> 17 </maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId> com.h2database </groupId>
<artifactId> h2 </artifactId>
<version> 2.1.214 </version>
<scope> test </scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId> org.hibernate </groupId>
<artifactId> hibernate-core </artifactId>
<version> 5.6.15.Final </version>
</dependency>
<dependency>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.13.2 </version>
<scope> test </scope>
</dependency>
</dependencies>
</project>
package org.example;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
@Entity
public class DummyUser {
@Id
@Column(name = "USER_ID" )
@GenericGenerator( name = "dummyuser_increment" ,strategy = "increment" )
@GeneratedValue(generator = "dummyuser_increment" )
private int userId;
@Column(name = "USER_NAME" ,nullable = false )
private String userName;
public DummyUser() {
}
public int getUserId() {
return userId;
}
public void setUserId( int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName( String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "DummyUser{" +
"userId=" + userId +
", userName= '" + userName + ' \'' +
'}' ;
}
}
Here is my test file
package org.example;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.NativeQuery;
import org.hibernate.type.StandardBasicTypes;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class DummyUserTest {
private final SessionFactory sessionFactory;
public DummyUserTest() {
sessionFactory = new Configuration().configure().buildSessionFactory();
// also adding data to database
Session session=sessionFactory.openSession();
DummyUser dummyUser= new DummyUser();
dummyUser.setUserName( "Joe Doe" );
Transaction transaction= session.beginTransaction();
session.persist( dummyUser );
transaction.commit();
session.close();
}
@Test
public void checkUniquenessOfAddScalar() {
String sql= "SELECT user_id FROM dummyuser WHERE user_name= 'Joe Doe' " ;
// obtaining session
Session session=sessionFactory.openSession();
NativeQuery< Integer > query=session.createNativeQuery( sql, Integer.class );
query.addScalar( "user_id" , StandardBasicTypes.INTEGER );
List< Integer > rsList = query.list();
assertNotNull( rsList );
assertEquals( 1, rsList.size() );
assertEquals( Integer.valueOf( 1 ), rsList.get(0) );
}
}
And finally this is my surefire test report which shows the exception
-------------------------------------------------------------------------------
Test set: org.example.DummyUserTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.803 sec <<< FAILURE!
checkUniquenessOfAddScalar(org.example.DummyUserTest) Time elapsed: 1.75 sec <<< ERROR!
javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown entity: java.lang.Integer
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1626)
at org.example.DummyUserTest.checkUniquenessOfAddScalar(DummyUserTest.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.hibernate.MappingException: Unknown entity: java.lang.Integer
at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:715)
at org.hibernate.engine.spi.SessionFactoryImplementor.getEntityPersister(SessionFactoryImplementor.java:360)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.getSQLLoadable(SQLQueryReturnProcessor.java:445)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processRootReturn(SQLQueryReturnProcessor.java:498)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processReturn(SQLQueryReturnProcessor.java:465)
at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.process(SQLQueryReturnProcessor.java:180)
at org.hibernate.loader.custom.sql.SQLCustomQuery.<init>(SQLCustomQuery.java:74)
at org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.createQueryPlan(NativeQueryInterpreterStandardImpl.java:44)
at org.hibernate.engine.query.spi.QueryPlanCache.getNativeSQLQueryPlan(QueryPlanCache.java:244)
at org.hibernate.internal.AbstractSharedSessionContract.getNativeQueryPlan(AbstractSharedSessionContract.java:640)
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1204)
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:177)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
... 33 more
@Puhog You could you please provide me snippets for a working test case in version 5.6.15 so that I may be able to better look into this issue.
( https://hibernate.atlassian.net/browse/HHH-16489#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16489#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100225- sha1:f83bc8f )
2 years, 11 months
[JIRA] (HHH-16550) Allow accessing the entity identifier from the UserType#nullSafeSet method
by François Rosière (JIRA)
François Rosière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYjcxYWMzNDhl... ) / Improvement ( https://hibernate.atlassian.net/browse/HHH-16550?atlOrigin=eyJpIjoiYjcxYW... ) HHH-16550 ( https://hibernate.atlassian.net/browse/HHH-16550?atlOrigin=eyJpIjoiYjcxYW... ) Allow accessing the entity identifier from the UserType#nullSafeSet method ( https://hibernate.atlassian.net/browse/HHH-16550?atlOrigin=eyJpIjoiYjcxYW... )
Issue Type: Improvement Affects Versions: 5.6.15, 6.2.2 Assignee: Unassigned Components: hibernate-core Created: 04/May/2023 04:44 AM Priority: Major Reporter: François Rosière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
Hibernate currently provides a way to define custom types. Either internal or user types.
In some situations, this custom type may have to access the entity identifier.
Concrete use case: compute a custom value using the entity identifier (may be null depending on the id strategy which is used).
This is currently possible from the nullSafeGet method through the owner but this is not possible to access that identifier from the nullSafeSet Method.
So, the proposal would be to review the Hibernate internals to allow exposing this identifier as follow on the UserType interface and call this new method instead of the current one
public interface UserType {
// hibernate would call this method internally
default void nullSafeSet(PreparedStatement st, Serializable id, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
nullSafeSet(st, value, index, session);
}
void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException;
}
The Type interface would also need to be updated the same way to allow transmitting the id from the caller stack. See CustomType.
Proposed change is retro-compatible.
( https://hibernate.atlassian.net/browse/HHH-16550#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16550#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100225- sha1:f83bc8f )
2 years, 11 months