Merge remote-tracking branch 'upstream/master' into wip/6.0
This commit is contained in:
commit
79c83cf8ba
|
@ -127,7 +127,7 @@ Use the following command:
|
|||
|
||||
gradle clean compile -Pdb=pgsql
|
||||
|
||||
_*NOTE: If you are running tests against a JDBC driver that is not available via Maven central (generally due to license nonsense - Oracle, DB2, etc) be sure to add these drivers to your local Maven repo cache (~/.m2/repository) or (better) add it to a personal Maven repo server*_
|
||||
_*NOTE: If you are running tests against a JDBC driver that is not available via Maven central be sure to add these drivers to your local Maven repo cache (~/.m2/repository) or (better) add it to a personal Maven repo server*_
|
||||
|
||||
Running database-specific tests from the IDE using "profiles"
|
||||
-------------------------------------------------------------
|
||||
|
|
|
@ -3,6 +3,33 @@ Hibernate 5 Changelog
|
|||
|
||||
Note: Please refer to JIRA to learn more about each issue.
|
||||
|
||||
Changes in 5.4.10.Final (December 05, 2019)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
https://hibernate.atlassian.net/projects/HHH/versions/31811/tab/release-report-done
|
||||
|
||||
** Bug
|
||||
* [HHH-9301] - Group by on alias doesn't replace alias
|
||||
* [HHH-12895] - Extra LEFT JOIN generated with @ManyToOne and @JoinTable when projecting on main entity id
|
||||
* [HHH-13355] - StaleStateException for updates to optional secondary table using saveOrUpdate
|
||||
* [HHH-13365] - Entities in joined subclass table are not inserted with batch size > 0 using sequence-identity ID generator
|
||||
* [HHH-13608] - Oracle8iDialect should use CASE_INSENSITIVE pattern matching when checking the statement type
|
||||
* [HHH-13722] - ArrayStoreException in Constraint.generateName
|
||||
* [HHH-13737] - Add debug logging and a test case for HHH-13433
|
||||
* [HHH-13742] - Missing from clause with joined inheritance property in association subquery
|
||||
* [HHH-13758] - Limit Handler for SQL server doesn't work with CTE queries with strings literals
|
||||
* [HHH-13764] - Annotations are ignored during enhancement if they are on the getter instead of the field
|
||||
|
||||
** Task
|
||||
* [HHH-13739] - Upgrade to Agroal 1.7
|
||||
* [HHH-13761] - Debug logging of JPA compliance settings didn't log the value of the settings
|
||||
* [HHH-13762] - Update vibur-dbcp dependency to 25.0
|
||||
|
||||
** Improvement
|
||||
* [HHH-8091] - Hibernate produces SQL - "in ()" - which is invalid in at least Oracle, MySQL and Postgres
|
||||
* [HHH-13755] - Update Hibernate Gradle Plugin example in the documentation
|
||||
|
||||
|
||||
Changes in 6.0.0.Alpha1 (November 23, 2019)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -30,7 +57,6 @@ https://hibernate.atlassian.net/projects/HHH/versions/31768/
|
|||
* [HHH-11990] - Remove LogicalConnectionImplementor#makeShareableCopy
|
||||
|
||||
|
||||
|
||||
Changes in 5.4.9.Final (November 14, 2019)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
apply plugin: 'org.hibernate.orm'
|
||||
|
||||
ext {
|
||||
hibernateVersion = 'hibernate-version-you-want'
|
||||
}
|
||||
|
@ -9,7 +11,9 @@ buildscript {
|
|||
}
|
||||
|
||||
hibernate {
|
||||
enhance {
|
||||
// any configuration goes here
|
||||
}
|
||||
enhance {
|
||||
enableLazyInitialization = true
|
||||
enableDirtyTracking = true
|
||||
enableAssociationManagement = true
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ ext {
|
|||
|
||||
agroalVersion = '1.7'
|
||||
|
||||
assertjVersion = '3.14.0'
|
||||
|
||||
geolatteVersion = '1.4.0'
|
||||
|
||||
// Wildfly version targeted by module ZIP; Arquillian/Shrinkwrap versions used for CDI testing and testing the module ZIP
|
||||
|
@ -147,7 +149,7 @@ ext {
|
|||
jcache: "javax.cache:cache-api:1.0.0",
|
||||
proxool: "proxool:proxool:0.8.3",
|
||||
hikaricp: "com.zaxxer:HikariCP:3.2.0",
|
||||
vibur: "org.vibur:vibur-dbcp:22.2",
|
||||
vibur: "org.vibur:vibur-dbcp:25.0",
|
||||
agroal_api: "io.agroal:agroal-api:${agroalVersion}",
|
||||
agroal_pool: "io.agroal:agroal-pool:${agroalVersion}",
|
||||
|
||||
|
@ -157,6 +159,8 @@ ext {
|
|||
cdi: "javax.enterprise:cdi-api:${cdiVersion}",
|
||||
weld: "org.jboss.weld.se:weld-se-shaded:${weldVersion}",
|
||||
|
||||
assertj: "org.assertj:assertj-core:${assertjVersion}",
|
||||
|
||||
// Arquillian/Shrinkwrap
|
||||
arquillian_junit_container: "org.jboss.arquillian.junit:arquillian-junit-container:${arquillianVersion}",
|
||||
arquillian_protocol_servlet: "org.jboss.arquillian.protocol:arquillian-protocol-servlet:${arquillianVersion}",
|
||||
|
|
|
@ -72,6 +72,7 @@ dependencies {
|
|||
testCompile( libraries.mockito )
|
||||
testCompile( libraries.mockito_inline )
|
||||
testCompile( libraries.jodaTime )
|
||||
testCompile( libraries.assertj )
|
||||
|
||||
testCompile( libraries.cdi ) {
|
||||
// we need to force it to make sure we influence the one coming from arquillian
|
||||
|
|
|
@ -536,7 +536,7 @@ public class EnhancerImpl implements Enhancer {
|
|||
}
|
||||
annotationDescriptions.addAll( fieldDescription.getDeclaredAnnotations() );
|
||||
|
||||
return fieldDescription.getDeclaredAnnotations();
|
||||
return new AnnotationList.Explicit( annotationDescriptions );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,10 +106,10 @@ public final class Settings {
|
|||
LOG.debugf( "Connection release mode: %s", sessionFactoryOptions.getConnectionReleaseMode() );
|
||||
LOG.debugf( "Generate SQL with comments: %s", enabledDisabled( sessionFactoryOptions.isCommentsEnabled() ) );
|
||||
|
||||
LOG.debugf( "JPA compliance - query : ", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaQueryComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - closed-handling : ", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaClosedComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - lists : ", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaListComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - transactions : ", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaTransactionComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - query : %s", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaQueryComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - closed-handling : %s", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaClosedComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - lists : %s", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaListComplianceEnabled() ) );
|
||||
LOG.debugf( "JPA compliance - transactions : %s", enabledDisabled( sessionFactoryOptions.getJpaCompliance().isJpaTransactionComplianceEnabled() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -585,7 +585,7 @@ public class SQLServer2005LimitHandler extends AbstractLimitHandler {
|
|||
int index = offset;
|
||||
boolean inString = false;
|
||||
for ( ; index < sql.length(); ++index ) {
|
||||
if ( sql.charAt( index ) == '\'' ) {
|
||||
if ( sql.charAt( index ) == '\'' && !inString ) {
|
||||
inString = true;
|
||||
}
|
||||
else if ( sql.charAt( index ) == '\'' && inString ) {
|
||||
|
|
|
@ -30,9 +30,4 @@ public abstract class AbstractPostInsertGenerator
|
|||
public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect dialect) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsJdbcBatchInserts() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,4 +18,9 @@ public interface PostInsertIdentifierGenerator extends IdentifierGenerator {
|
|||
PostInsertIdentityPersister persister,
|
||||
Dialect dialect,
|
||||
boolean isGetGeneratedKeysEnabled) throws HibernateException;
|
||||
|
||||
@Override
|
||||
default boolean supportsJdbcBatchInserts() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3399,7 +3399,18 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
final Expectation expectation = Expectations.appropriateExpectation( updateResultCheckStyles[j] );
|
||||
final int jdbcBatchSizeToUse = session.getConfiguredJdbcBatchSize();
|
||||
final boolean useBatch = expectation.canBeBatched() && isBatchable() && jdbcBatchSizeToUse > 1;
|
||||
// IMPLEMENTATION NOTE: If Session#saveOrUpdate or #update is used to update an entity, then
|
||||
// Hibernate does not have a database snapshot of the existing entity.
|
||||
// As a result, oldFields will be null.
|
||||
// Don't use a batch if oldFields == null and the jth table is optional (isNullableTable( j ),
|
||||
// because there is no way to know that there is actually a row to update. If the update
|
||||
// was batched in this case, the batch update would fail and there is no way to fallback to
|
||||
// an insert.
|
||||
final boolean useBatch =
|
||||
expectation.canBeBatched() &&
|
||||
isBatchable() &&
|
||||
jdbcBatchSizeToUse > 1 &&
|
||||
( oldFields != null || !isNullableTable( j ) );
|
||||
if ( useBatch && updateBatchKey == null ) {
|
||||
updateBatchKey = new BasicBatchKey(
|
||||
getEntityName() + "#UPDATE",
|
||||
|
|
|
@ -8,26 +8,22 @@ package org.hibernate.jpa.test.criteria.basic;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.dialect.Oracle12cDialect;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
import org.hibernate.dialect.Oracle9Dialect;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.jpa.test.metamodel.AbstractMetamodelSpecificTest;
|
||||
import org.hibernate.jpa.test.metamodel.CreditCard;
|
||||
import org.hibernate.jpa.test.metamodel.CreditCard_;
|
||||
import org.hibernate.jpa.test.metamodel.Customer_;
|
||||
import org.hibernate.jpa.test.metamodel.Order;
|
||||
import org.hibernate.jpa.test.metamodel.Order_;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Before;
|
||||
|
@ -297,4 +293,21 @@ public class PredicateTest extends AbstractMetamodelSpecificTest {
|
|||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature( DialectChecks.NotSupportsEmptyInListCheck.class )
|
||||
public void testEmptyInPredicate() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
||||
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
||||
orderCriteria.select( orderRoot );
|
||||
orderCriteria.where( builder.in( orderRoot.get("totalPrice") ) );
|
||||
|
||||
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
||||
assertTrue( orders.isEmpty() );
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.bytecode.enhance.internal.bytebuddy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.bytecode.enhance.internal.tracker.CompositeOwnerTracker;
|
||||
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_ENTRY_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_ENTRY_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_SETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_SETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_CLEAR_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_CLEAR_OWNER;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_SET_OWNER;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_GET_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_HAS_CHANGED_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_SUSPEND_NAME;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-13764")
|
||||
@RunWith(BytecodeEnhancerRunner.class)
|
||||
@EnhancementOptions(inlineDirtyChecking = true)
|
||||
public class DirtyCheckingWithEmbeddedOnGetterTest {
|
||||
|
||||
@Test
|
||||
public void shouldDeclareFieldsInEntityClass() {
|
||||
assertThat( CardGame.class )
|
||||
.hasDeclaredFields( ENTITY_ENTRY_FIELD_NAME, PREVIOUS_FIELD_NAME, NEXT_FIELD_NAME, TRACKER_FIELD_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareMethodsInEntityClass() {
|
||||
assertThat( CardGame.class )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "id", PERSISTENT_FIELD_WRITER_PREFIX + "id" )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "name", PERSISTENT_FIELD_WRITER_PREFIX + "name" )
|
||||
.hasDeclaredMethods( ENTITY_INSTANCE_GETTER_NAME, ENTITY_ENTRY_GETTER_NAME )
|
||||
.hasDeclaredMethods( PREVIOUS_GETTER_NAME, PREVIOUS_SETTER_NAME, NEXT_GETTER_NAME, NEXT_SETTER_NAME )
|
||||
.hasDeclaredMethods( TRACKER_HAS_CHANGED_NAME, TRACKER_CLEAR_NAME, TRACKER_SUSPEND_NAME, TRACKER_GET_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareFieldsInEmbeddedClass() {
|
||||
assertThat( Component.class )
|
||||
.hasDeclaredFields( TRACKER_COMPOSITE_FIELD_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareMethodsInEmbeddedClass() {
|
||||
assertThat( Component.class )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "component", PERSISTENT_FIELD_WRITER_PREFIX + "component" )
|
||||
.hasDeclaredMethods( TRACKER_COMPOSITE_SET_OWNER, TRACKER_COMPOSITE_CLEAR_OWNER );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTheTracker() throws Exception {
|
||||
CardGame entity = new CardGame( "MTG", "Magic the Gathering" );
|
||||
assertThat( entity )
|
||||
.extracting( NEXT_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( PREVIOUS_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( ENTITY_ENTRY_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( TRACKER_FIELD_NAME ).isInstanceOf( SimpleFieldTracker.class );
|
||||
assertThat( entity.getFirstPlayerToken() )
|
||||
.extracting( TRACKER_COMPOSITE_FIELD_NAME ).isInstanceOf( CompositeOwnerTracker.class );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( true );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "name", "firstPlayerToken" } );
|
||||
assertThat( entity.getFirstPlayerToken() ).extracting( TRACKER_COMPOSITE_FIELD_NAME + ".names" )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldResetTheTracker() throws Exception {
|
||||
CardGame entity = new CardGame( "7WD", "7 WOnders duel" );
|
||||
|
||||
Method trackerClearMethod = CardGame.class.getMethod( TRACKER_CLEAR_NAME );
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( false );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME ).isEqualTo( new String[0] );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateTheTracker() throws Exception {
|
||||
Assertions.setAllowExtractingPrivateFields( true );
|
||||
CardGame entity = new CardGame( "SPL", "Splendor" );
|
||||
|
||||
Method trackerClearMethod = CardGame.class.getMethod( TRACKER_CLEAR_NAME );
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
entity.setName( "Splendor: Cities of Splendor" );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( true );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "name", "firstPlayerToken" } );
|
||||
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
entity.setFirstPlayerToken( new Component( "FIRST PLAYER!!!!!!!!" ) );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
|
||||
assertThat( entity.getFirstPlayerToken() ).extracting( TRACKER_COMPOSITE_FIELD_NAME + ".names" )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class Component {
|
||||
@Column(name = "first_player_token")
|
||||
private String component;
|
||||
|
||||
public Component() {
|
||||
}
|
||||
|
||||
private Component(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public String getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setComponent(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "CardGame")
|
||||
public static class CardGame {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
private Component firstPlayerToken;
|
||||
|
||||
public CardGame() {
|
||||
}
|
||||
|
||||
private CardGame(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.firstPlayerToken = createEmbeddedValue( name );
|
||||
}
|
||||
|
||||
@Id
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
this.firstPlayerToken = createEmbeddedValue( name );
|
||||
}
|
||||
|
||||
@Embedded
|
||||
public Component getFirstPlayerToken() {
|
||||
return firstPlayerToken;
|
||||
}
|
||||
|
||||
public void setFirstPlayerToken(Component firstPlayerToken) {
|
||||
this.firstPlayerToken = firstPlayerToken;
|
||||
}
|
||||
|
||||
private Component createEmbeddedValue(String name) {
|
||||
return new Component( name + " first player token" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.bytecode.enhance.internal.bytebuddy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.bytecode.enhance.internal.tracker.CompositeOwnerTracker;
|
||||
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_ENTRY_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_ENTRY_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.ENTITY_INSTANCE_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.NEXT_SETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_GETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.PREVIOUS_SETTER_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_CLEAR_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_CLEAR_OWNER;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_COMPOSITE_SET_OWNER;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_FIELD_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_GET_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_HAS_CHANGED_NAME;
|
||||
import static org.hibernate.bytecode.enhance.spi.EnhancerConstants.TRACKER_SUSPEND_NAME;
|
||||
|
||||
@TestForIssue(jiraKey = "HHH-13764")
|
||||
@RunWith(BytecodeEnhancerRunner.class)
|
||||
@EnhancementOptions(inlineDirtyChecking = true)
|
||||
public class DirtyCheckingWithEmbeddedTest {
|
||||
|
||||
@Test
|
||||
public void shouldDeclareFieldsInEntityClass() {
|
||||
assertThat( CardGame.class )
|
||||
.hasDeclaredFields( ENTITY_ENTRY_FIELD_NAME, PREVIOUS_FIELD_NAME, NEXT_FIELD_NAME, TRACKER_FIELD_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareMethodsInEntityClass() {
|
||||
assertThat( CardGame.class )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "id", PERSISTENT_FIELD_WRITER_PREFIX + "id" )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "name", PERSISTENT_FIELD_WRITER_PREFIX + "name" )
|
||||
.hasDeclaredMethods( ENTITY_INSTANCE_GETTER_NAME, ENTITY_ENTRY_GETTER_NAME )
|
||||
.hasDeclaredMethods( PREVIOUS_GETTER_NAME, PREVIOUS_SETTER_NAME, NEXT_GETTER_NAME, NEXT_SETTER_NAME )
|
||||
.hasDeclaredMethods( TRACKER_HAS_CHANGED_NAME, TRACKER_CLEAR_NAME, TRACKER_SUSPEND_NAME, TRACKER_GET_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareFieldsInEmbeddedClass() {
|
||||
assertThat( Component.class )
|
||||
.hasDeclaredFields( TRACKER_COMPOSITE_FIELD_NAME );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeclareMethodsInEmbeddedClass() {
|
||||
assertThat( Component.class )
|
||||
.hasDeclaredMethods( PERSISTENT_FIELD_READER_PREFIX + "component", PERSISTENT_FIELD_WRITER_PREFIX + "component" )
|
||||
.hasDeclaredMethods( TRACKER_COMPOSITE_SET_OWNER, TRACKER_COMPOSITE_CLEAR_OWNER );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateTheTracker() throws Exception {
|
||||
CardGame entity = new CardGame( "MTG", "Magic the Gathering" );
|
||||
assertThat( entity )
|
||||
.extracting( NEXT_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( PREVIOUS_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( ENTITY_ENTRY_FIELD_NAME ).isNull();
|
||||
assertThat( entity )
|
||||
.extracting( TRACKER_FIELD_NAME ).isInstanceOf( SimpleFieldTracker.class );
|
||||
assertThat( entity.getFirstPlayerToken() )
|
||||
.extracting( TRACKER_COMPOSITE_FIELD_NAME ).isInstanceOf( CompositeOwnerTracker.class );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( true );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "name", "firstPlayerToken" } );
|
||||
assertThat( entity.getFirstPlayerToken() ).extracting( TRACKER_COMPOSITE_FIELD_NAME + ".names" )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldResetTheTracker() throws Exception {
|
||||
CardGame entity = new CardGame( "7WD", "7 WOnders duel" );
|
||||
|
||||
Method trackerClearMethod = CardGame.class.getMethod( TRACKER_CLEAR_NAME );
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( false );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME ).isEqualTo( new String[0] );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateTheTracker() throws Exception {
|
||||
Assertions.setAllowExtractingPrivateFields( true );
|
||||
CardGame entity = new CardGame( "SPL", "Splendor" );
|
||||
|
||||
Method trackerClearMethod = CardGame.class.getMethod( TRACKER_CLEAR_NAME );
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
entity.setName( "Splendor: Cities of Splendor" );
|
||||
|
||||
assertThat( entity ).extracting( TRACKER_HAS_CHANGED_NAME ).isEqualTo( true );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "name", "firstPlayerToken" } );
|
||||
|
||||
trackerClearMethod.invoke( entity );
|
||||
|
||||
entity.setFirstPlayerToken( new Component( "FIRST PLAYER!!!!!!!!" ) );
|
||||
assertThat( entity ).extracting( TRACKER_GET_NAME )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
|
||||
assertThat( entity.getFirstPlayerToken() ).extracting( TRACKER_COMPOSITE_FIELD_NAME + ".names" )
|
||||
.isEqualTo( new String[] { "firstPlayerToken" } );
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class Component {
|
||||
@Column(name = "first_player_token")
|
||||
private String component;
|
||||
|
||||
public Component() {
|
||||
}
|
||||
|
||||
private Component(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public String getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
public void setComponent(String component) {
|
||||
this.component = component;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "CardGame")
|
||||
public static class CardGame {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
@Embedded
|
||||
private Component firstPlayerToken;
|
||||
|
||||
public CardGame() {
|
||||
}
|
||||
|
||||
private CardGame(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.firstPlayerToken = createEmbeddedValue( name );
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
this.firstPlayerToken = createEmbeddedValue( name );
|
||||
}
|
||||
|
||||
public Component getFirstPlayerToken() {
|
||||
return firstPlayerToken;
|
||||
}
|
||||
|
||||
public void setFirstPlayerToken(Component firstPlayerToken) {
|
||||
this.firstPlayerToken = firstPlayerToken;
|
||||
}
|
||||
|
||||
private Component createEmbeddedValue(String name) {
|
||||
return new Component( name + " first player token" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -90,7 +90,7 @@ public class GroupByAliasTest extends BaseEntityManagerFunctionalTestCase {
|
|||
List<Tuple> list = doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p.association as id_alias, sum(p.age) " +
|
||||
"from Person p group by id_alias order by id_alias", Tuple.class)
|
||||
"from Person p group by id_alias, p.association.id, p.association.name order by id_alias", Tuple.class)
|
||||
.getResultList();
|
||||
});
|
||||
|
||||
|
@ -105,7 +105,7 @@ public class GroupByAliasTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
List<Tuple> list = doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p.id as id_alias_1, p.association as id_alias_2, sum(p.age) " +
|
||||
"select p.id as id_alias_1, p.association.id as id_alias_2, sum(p.age) " +
|
||||
"from Person p group by id_alias_1, id_alias_2 order by id_alias_1, id_alias_2 ", Tuple.class)
|
||||
.getResultList();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* 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.batch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SecondaryTable;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import org.hibernate.annotations.Table;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class OptionalSecondaryTableBatchTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
private List<Company> companies;
|
||||
|
||||
@Test
|
||||
public void testMerge() {
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
final Company company = companies.get( i );
|
||||
company.taxNumber = 2 * i;
|
||||
session.merge( company );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
assertEquals( Integer.valueOf( 2 * i ), session.get( Company.class, i).taxNumber );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveOrUpdate() {
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
final Company company = companies.get( i );
|
||||
company.taxNumber = 2 * i;
|
||||
session.saveOrUpdate( company );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
assertEquals( Integer.valueOf( 2 * i ), session.get( Company.class, i).taxNumber );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
final Company company = companies.get( i );
|
||||
company.taxNumber = 2 * i;
|
||||
session.update( company );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0 ; i < 10 ; i++ ) {
|
||||
assertEquals( Integer.valueOf( 2 * i ), session.get( Company.class, i).taxNumber );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] { Company.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSettings(Map settings) {
|
||||
super.addSettings( settings );
|
||||
settings.put( AvailableSettings.STATEMENT_BATCH_SIZE, 5 );
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupData() {
|
||||
companies = new ArrayList<>( 10 );
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
for ( int i = 0; i < 10; i++ ) {
|
||||
final Company company = new Company();
|
||||
company.id = i;
|
||||
if ( i % 2 == 0 ) {
|
||||
company.taxNumber = i;
|
||||
}
|
||||
session.persist( company );
|
||||
companies.add( company );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanupData() {
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
session.createQuery( "delete from Company" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Company")
|
||||
@SecondaryTable( name = "company_tax" )
|
||||
@Table( appliesTo = "company_tax", optional = true)
|
||||
public static class Company {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@Version
|
||||
@Column( name = "ver" )
|
||||
private int version;
|
||||
|
||||
private String name;
|
||||
|
||||
@Column(table = "company_tax")
|
||||
private Integer taxNumber;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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.generatedkeys.seqidentity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
import javax.persistence.DiscriminatorType;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Parameter;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Oracle9iDialect;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@TestForIssue( jiraKey = "HHH-13365" )
|
||||
@RequiresDialect( Oracle9iDialect.class )
|
||||
public class JoinedSequenceIdentityBatchTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
@Test
|
||||
public void testInsertAndUpdate() {
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
FolderResource folder = new FolderResource();
|
||||
folder.name = "PARENT";
|
||||
session.persist( folder );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
List<FolderResource> folderResources = session.createQuery( "from FolderResource" ).getResultList();
|
||||
assertEquals( 1, folderResources.size() );
|
||||
final FolderResource folderResource = folderResources.get( 0 );
|
||||
assertNull( folderResource.description );
|
||||
folderResource.description = "A folder resource";
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory,
|
||||
session -> {
|
||||
List<FolderResource> folderResources = session.createQuery( "from FolderResource" ).getResultList();
|
||||
assertEquals( 1, folderResources.size() );
|
||||
final FolderResource folderResource = folderResources.get( 0 );
|
||||
assertEquals( "A folder resource", folderResource.description );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "unchecked" )
|
||||
protected void addSettings(Map settings) {
|
||||
super.addSettings( settings );
|
||||
settings.put( AvailableSettings.STATEMENT_BATCH_SIZE, "5" );
|
||||
settings.put( AvailableSettings.USE_GET_GENERATED_KEYS, "true" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] { Resource.class, FolderResource.class };
|
||||
}
|
||||
|
||||
@Entity(name = "Resource")
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
@Table(name = "WORKSPACE_RESOURCE")
|
||||
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
|
||||
public static class Resource {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_WORKSPACE_RESOURCE")
|
||||
@GenericGenerator(name = "SEQ_WORKSPACE_RESOURCE", strategy = "sequence-identity",
|
||||
parameters = {@Parameter(name = "sequence", value = "SEQ_WORKSPACE_RESOURCE")})
|
||||
@Column(name = "ID_WORKSPACE_RESOURCE", nullable = false, precision = 18)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "NAME", nullable = false, length = 256)
|
||||
protected String name;
|
||||
|
||||
@Column(name = "RESOURCE_TYPE", nullable = false, length = 20)
|
||||
protected String type;
|
||||
}
|
||||
|
||||
@Entity(name = "FolderResource")
|
||||
@Table(name = "WORKSPACE_RESOURCE_FOLDER")
|
||||
@PrimaryKeyJoinColumn(name = "ID_WORKSPACE_RESOURCE_FOLDER")
|
||||
@DiscriminatorValue("FOLDER")
|
||||
public static class FolderResource extends Resource implements Serializable {
|
||||
private String description;
|
||||
|
||||
public FolderResource()
|
||||
{
|
||||
super();
|
||||
type = "FOLDER";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,18 @@
|
|||
*/
|
||||
package org.hibernate.test.hql;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertClassAssignability;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Date;
|
||||
|
@ -13,11 +25,11 @@ import java.sql.Time;
|
|||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.QueryException;
|
||||
|
@ -79,6 +91,18 @@ import org.hibernate.test.cid.LineItem;
|
|||
import org.hibernate.test.cid.LineItem.Id;
|
||||
import org.hibernate.test.cid.Order;
|
||||
import org.hibernate.test.cid.Product;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.transform.DistinctRootEntityResultTransformer;
|
||||
import org.hibernate.transform.Transformers;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.ManyToOneType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
|
@ -675,6 +699,35 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
|||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature(DialectChecks.NotSupportsEmptyInListCheck.class)
|
||||
public void testEmptyInListForDialectsNotSupportsEmptyInList() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
Human human = new Human();
|
||||
human.setName( new Name( "Lukasz", null, "Antoniak" ) );
|
||||
human.setNickName( "NONE" );
|
||||
session.save( human );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
List results = session.createQuery( "from Human h where h.nickName in (:nickNames)" )
|
||||
.setParameter("nickNames", Collections.emptySet() )
|
||||
.list();
|
||||
assertEquals( 0, results.size() );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
session.delete( human );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-2851")
|
||||
public void testMultipleRefsToSameParam() {
|
||||
|
@ -958,7 +1011,7 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
|||
// simple syntax checking...
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
s.createQuery( "from Human h wherFe h.nickName = '1' || 'ov' || 'tha' || 'few'" ).list();
|
||||
s.createQuery( "from Human h where h.nickName = '1' || 'ov' || 'tha' || 'few'" ).list();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class QueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
|
||||
// test Query w/ a simple Oracle optimizer hint
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "FROM QueryHintTest$Employee e WHERE e.department.name = :departmentName" )
|
||||
Query query = s.createQuery( "FROM Employee e WHERE e.department.name = :departmentName" )
|
||||
.addQueryHint( "ALL_ROWS" )
|
||||
.setParameter( "departmentName", "Sales" );
|
||||
List results = query.list();
|
||||
|
@ -89,7 +89,7 @@ public class QueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
|
||||
// test multiple hints
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "FROM QueryHintTest$Employee e WHERE e.department.name = :departmentName" )
|
||||
Query query = s.createQuery( "FROM Employee e WHERE e.department.name = :departmentName" )
|
||||
.addQueryHint( "ALL_ROWS" )
|
||||
.addQueryHint( "USE_CONCAT" )
|
||||
.setParameter( "departmentName", "Sales" );
|
||||
|
@ -104,7 +104,7 @@ public class QueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
|
||||
// ensure the insertion logic can handle a comment appended to the front
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "FROM QueryHintTest$Employee e WHERE e.department.name = :departmentName" )
|
||||
Query query = s.createQuery( "FROM Employee e WHERE e.department.name = :departmentName" )
|
||||
.setComment( "this is a test" )
|
||||
.addQueryHint( "ALL_ROWS" )
|
||||
.setParameter( "departmentName", "Sales" );
|
||||
|
@ -147,7 +147,7 @@ public class QueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
sqlStatementInterceptor.clear();
|
||||
|
||||
doInHibernate( this::sessionFactory, s -> {
|
||||
Query query = s.createQuery( "FROM QueryHintTest$Employee e WHERE e.department.name = :departmentName" )
|
||||
Query query = s.createQuery( "FROM Employee e WHERE e.department.name = :departmentName" )
|
||||
.addQueryHint( "ALL_ROWS" )
|
||||
.setComment( "My_Query" )
|
||||
.setParameter( "departmentName", "Sales" );
|
||||
|
|
|
@ -8,11 +8,15 @@ package org.hibernate.test.criteria;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -42,4 +46,30 @@ public class InTest extends BaseCoreFunctionalTestCase {
|
|||
tx.rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature(DialectChecks.NotSupportsEmptyInListCheck.class)
|
||||
public void testEmptyInListForDialectNotSupportsEmptyInList() {
|
||||
Session session = openSession();
|
||||
Transaction tx = session.beginTransaction();
|
||||
session.save( new Woman() );
|
||||
session.save( new Man() );
|
||||
session.flush();
|
||||
tx.commit();
|
||||
session.close();
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
List persons = session.createCriteria( Person.class ).add(
|
||||
Restrictions.in( "name", Collections.emptySet() ) ).list();
|
||||
assertEquals( 0, persons.size() );
|
||||
tx.rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCleanupTestDataRequired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,12 @@ abstract public class DialectChecks {
|
|||
}
|
||||
}
|
||||
|
||||
public static class NotSupportsEmptyInListCheck implements DialectCheck {
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return !dialect.supportsEmptyInList();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CaseSensitiveCheck implements DialectCheck {
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return dialect.areStringComparisonsCaseInsensitive();
|
||||
|
|
Loading…
Reference in New Issue