Fix issue with fetch a ManyToOne with join table using inner join

This commit is contained in:
Andrea Boriero 2020-06-17 18:29:19 +01:00
parent cdc0e3f817
commit 7fd6e4fbea
8 changed files with 76 additions and 55 deletions

View File

@ -343,6 +343,7 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
sqlAstJoinType = SqlAstJoinType.INNER;
}
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
fetchablePath,
parentTableGroup,

View File

@ -29,6 +29,7 @@ import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
import org.hibernate.query.sqm.tree.expression.Conversion;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.expression.Any;
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
@ -436,7 +437,11 @@ public abstract class AbstractSqlAstWalker
}
else {
appendSql( EMPTY_STRING );
appendSql( tableGroupJoin.getJoinType().getText() );
SqlAstJoinType joinType = tableGroupJoin.getJoinType();
if ( joinType == SqlAstJoinType.INNER && !joinedGroup.getTableReferenceJoins().isEmpty() ) {
joinType = SqlAstJoinType.LEFT;
}
appendSql( joinType.getText() );
appendSql( " join " );
if ( tableGroupJoin.getPredicate() != null && !tableGroupJoin.getPredicate().isEmpty() ) {

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations.mappedsuperclass.intermediate;
package org.hibernate.orm.test.annotations.mappedsuperclass.intermediate;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations.mappedsuperclass.intermediate;
package org.hibernate.orm.test.annotations.mappedsuperclass.intermediate;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

View File

@ -0,0 +1,65 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.mappedsuperclass.intermediate;
import java.math.BigDecimal;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Steve Ebersole
*/
@DomainModel(
annotatedClasses = {
AccountBase.class, Account.class, SavingsAccountBase.class, SavingsAccount.class
}
)
@SessionFactory
public class IntermediateMappedSuperclassTest {
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createQuery( "from Account" ).list().forEach(
account -> session.delete( account )
);
}
);
}
@Test
public void testGetOnIntermediateMappedSuperclass(SessionFactoryScope scope) {
final BigDecimal withdrawalLimit = new BigDecimal( 1000.00 ).setScale( 2 );
SavingsAccount savingsAccount = new SavingsAccount( "123", withdrawalLimit );
scope.inTransaction(
session -> {
session.save( savingsAccount );
}
);
scope.inTransaction(
session -> {
Account account = session.get( Account.class, savingsAccount.getId() );
// Oracle returns the BigDecimal with scale=0, which is equal to 1000 (not 1000.00);
// compare using BigDecimal.doubleValue;
assertEquals(
withdrawalLimit.doubleValue(),
( (SavingsAccount) account ).getWithdrawalLimit().doubleValue(),
0.001
);
}
);
}
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations.mappedsuperclass.intermediate;
package org.hibernate.orm.test.annotations.mappedsuperclass.intermediate;
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations.mappedsuperclass.intermediate;
package org.hibernate.orm.test.annotations.mappedsuperclass.intermediate;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;

View File

@ -1,50 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations.mappedsuperclass.intermediate;
import java.math.BigDecimal;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
public class IntermediateMappedSuperclassTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { AccountBase.class, Account.class, SavingsAccountBase.class, SavingsAccount.class };
}
@Test
public void testGetOnIntermediateMappedSuperclass() {
final BigDecimal withdrawalLimit = new BigDecimal( 1000.00 ).setScale( 2 );
Session session = openSession();
session.beginTransaction();
SavingsAccount savingsAccount = new SavingsAccount( "123", withdrawalLimit );
session.save( savingsAccount );
session.getTransaction().commit();
session.close();
session = openSession();
session.beginTransaction();
Account account = (Account) session.get( Account.class, savingsAccount.getId() );
// Oracle returns the BigDecimal with scale=0, which is equal to 1000 (not 1000.00);
// compare using BigDecimal.doubleValue;
assertEquals(
withdrawalLimit.doubleValue(),
( (SavingsAccount) account ).getWithdrawalLimit().doubleValue(),
0.001);
session.delete( account );
session.getTransaction().commit();
session.close();
}
}