Merge remote-tracking branch 'upstream/master' into wip/6.0_merge_49
This commit is contained in:
commit
de3359537f
|
@ -264,7 +264,9 @@ If for some reason it is not able to determine the proper one or you want to use
|
|||
[width="100%",cols="28%,72%",options="header",]
|
||||
|=======================================================================
|
||||
|Dialect (short name) |Remarks
|
||||
|Cache71 |Support for the Caché database, version 2007.1
|
||||
|Cache71 |Support for the Caché database, version 2007.1.
|
||||
|CockroachDB192 |Support for the CockroachDB database version 19.2.
|
||||
|CockroachDB201 |Support for the CockroachDB database version 20.1.
|
||||
|CUBRID |Support for the CUBRID database, version 8.3. May work with later versions.
|
||||
|DB2 |Support for the DB2 database, version 8.2.
|
||||
|DB297 |Support for the DB2 database, version 9.7.
|
||||
|
|
|
@ -206,7 +206,7 @@ public class SecondLevelCacheTest extends BaseEntityManagerFunctionalTestCase {
|
|||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::caching-management-cache-mode-entity-jpa-example[]
|
||||
Map<String, Object> hints = new HashMap<>( );
|
||||
hints.put( "javax.persistence.cache.retrieveMode " , CacheRetrieveMode.USE );
|
||||
hints.put( "javax.persistence.cache.retrieveMode" , CacheRetrieveMode.USE );
|
||||
hints.put( "javax.persistence.cache.storeMode" , CacheStoreMode.REFRESH );
|
||||
Person person = entityManager.find( Person.class, 1L , hints);
|
||||
//end::caching-management-cache-mode-entity-jpa-example[]
|
||||
|
@ -225,7 +225,7 @@ public class SecondLevelCacheTest extends BaseEntityManagerFunctionalTestCase {
|
|||
List<Person> persons = entityManager.createQuery(
|
||||
"select p from Person p", Person.class)
|
||||
.setHint( QueryHints.HINT_CACHEABLE, "true")
|
||||
.setHint( "javax.persistence.cache.retrieveMode " , CacheRetrieveMode.USE )
|
||||
.setHint( "javax.persistence.cache.retrieveMode" , CacheRetrieveMode.USE )
|
||||
.setHint( "javax.persistence.cache.storeMode" , CacheStoreMode.REFRESH )
|
||||
.getResultList();
|
||||
//end::caching-management-cache-mode-query-jpa-example[]
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en
|
||||
# Keep system properties in sync with test system properties (java-module.gradle)!
|
||||
org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8
|
||||
|
|
|
@ -242,6 +242,14 @@ processTestResources {
|
|||
filter( ReplaceTokens, tokens: dbBundle[db] )
|
||||
}
|
||||
|
||||
// Keep system properties in sync with gradle.properties!
|
||||
test {
|
||||
systemProperty 'user.language', 'en'
|
||||
systemProperty 'user.country', 'US'
|
||||
systemProperty 'user.timezone', 'UTC'
|
||||
systemProperty 'file.encoding', 'UTF-8'
|
||||
}
|
||||
|
||||
// Enable the experimental features of ByteBuddy with JDK 15+
|
||||
test {
|
||||
if ( Integer.valueOf( gradle.ext.testedJavaVersionAsEnum.getMajorVersion() ) >= 15 ) {
|
||||
|
|
|
@ -10,6 +10,8 @@ import java.util.Objects;
|
|||
|
||||
import org.hibernate.dialect.CUBRIDDialect;
|
||||
import org.hibernate.dialect.Cache71Dialect;
|
||||
import org.hibernate.dialect.CockroachDB192Dialect;
|
||||
import org.hibernate.dialect.CockroachDB201Dialect;
|
||||
import org.hibernate.dialect.DB2390Dialect;
|
||||
import org.hibernate.dialect.DB2390V8Dialect;
|
||||
import org.hibernate.dialect.DB2400Dialect;
|
||||
|
@ -80,6 +82,12 @@ public class DefaultDialectSelector implements LazyServiceResolver<Dialect> {
|
|||
if ( name.equals( "Cache71" ) ) {
|
||||
return Cache71Dialect.class;
|
||||
}
|
||||
if ( name.equals( "CockroachDB192" ) ) {
|
||||
return CockroachDB192Dialect.class;
|
||||
}
|
||||
if ( name.equals( "CockroachDB201" ) ) {
|
||||
return CockroachDB201Dialect.class;
|
||||
}
|
||||
if ( name.equals( "CUBRID" ) ) {
|
||||
return CUBRIDDialect.class;
|
||||
}
|
||||
|
|
|
@ -350,6 +350,7 @@ class TypeSafeActivator {
|
|||
}
|
||||
hasNotNull = true;
|
||||
}
|
||||
property.setOptional( !hasNotNull );
|
||||
return hasNotNull;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
private final boolean connectionProvided;
|
||||
private final boolean allowBytecodeProxy;
|
||||
|
||||
StatelessSessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
|
||||
public StatelessSessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
|
||||
super( factory, options );
|
||||
connectionProvided = options.getConnection() != null;
|
||||
allowBytecodeProxy = getFactory().getSessionFactoryOptions().isEnhancementAsProxyEnabled();
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.sql.SQLException;
|
|||
|
||||
import org.hibernate.ConnectionAcquisitionMode;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.ResourceClosedException;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
@ -27,6 +28,9 @@ import org.jboss.logging.Logger;
|
|||
|
||||
/**
|
||||
* Represents a LogicalConnection where we manage obtaining and releasing the Connection as needed.
|
||||
* This implementation does not claim to be threadsafe and is not designed to be used by multiple
|
||||
* threads, yet we do apply a limited amount of care to be able to void obscure exceptions when
|
||||
* this class is used in the wrong way.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -189,23 +193,33 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
|||
}
|
||||
|
||||
private void releaseConnection() {
|
||||
if ( physicalConnection == null ) {
|
||||
//Some managed containers might trigger this release concurrently:
|
||||
//this is not how they should do things, still we make a local
|
||||
//copy of the variable to prevent confusing errors due to a race conditions
|
||||
//(to trigger a more clear error, if any).
|
||||
final Connection localVariableConnection = this.physicalConnection;
|
||||
if ( localVariableConnection == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if ( !physicalConnection.isClosed() ) {
|
||||
sqlExceptionHelper.logAndClearWarnings( physicalConnection );
|
||||
if ( ! localVariableConnection.isClosed() ) {
|
||||
sqlExceptionHelper.logAndClearWarnings( localVariableConnection );
|
||||
}
|
||||
jdbcConnectionAccess.releaseConnection( physicalConnection );
|
||||
jdbcConnectionAccess.releaseConnection( localVariableConnection );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw sqlExceptionHelper.convert( e, "Unable to release JDBC Connection" );
|
||||
}
|
||||
finally {
|
||||
observer.jdbcConnectionReleaseEnd();
|
||||
physicalConnection = null;
|
||||
boolean concurrentUsageDetected = ( this.physicalConnection == null );
|
||||
this.physicalConnection = null;
|
||||
getResourceRegistry().releaseResources();
|
||||
if ( concurrentUsageDetected ) {
|
||||
throw new HibernateException( "Detected concurrent management of connection resources." +
|
||||
" This might indicate a multi-threaded use of Hibernate in combination with managed resources, which is not supported." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,11 +74,8 @@ public class MaxInExpressionParameterPaddingTest extends BaseEntityManagerFuncti
|
|||
sqlStatementInterceptor.clear();
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p " +
|
||||
"from Person p " +
|
||||
"where p.id in :ids" )
|
||||
.setParameter( "ids", IntStream.range( 0, MAX_COUNT ).boxed().collect(Collectors.toList()) )
|
||||
return entityManager.createQuery( "select p from Person p where p.id in :ids" )
|
||||
.setParameter( "ids", IntStream.range( 0, MAX_COUNT ).boxed().collect( Collectors.toList() ) )
|
||||
.getResultList();
|
||||
} );
|
||||
|
||||
|
@ -89,6 +86,30 @@ public class MaxInExpressionParameterPaddingTest extends BaseEntityManagerFuncti
|
|||
}
|
||||
expectedInClause.append( ")" );
|
||||
|
||||
assertTrue( sqlStatementInterceptor.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ) );
|
||||
}
|
||||
|
||||
@TestForIssue( jiraKey = "HHH-14109" )
|
||||
@Test
|
||||
public void testInClauseParameterPaddingToLimit() {
|
||||
sqlStatementInterceptor.clear();
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
return entityManager.createQuery(
|
||||
"select p " +
|
||||
"from Person p " +
|
||||
"where p.id in :ids" )
|
||||
.setParameter( "ids", IntStream.range( 0, 10 ).boxed().collect(Collectors.toList()) )
|
||||
.getResultList();
|
||||
} );
|
||||
|
||||
StringBuilder expectedInClause = new StringBuilder();
|
||||
expectedInClause.append( "in (?" );
|
||||
for ( int i = 1; i < MAX_COUNT; i++ ) {
|
||||
expectedInClause.append( " , ?" );
|
||||
}
|
||||
expectedInClause.append( ")" );
|
||||
|
||||
assertTrue(sqlStatementInterceptor.getSqlQueries().get( 0 ).endsWith( expectedInClause.toString() ));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package org.hibernate.test.annotations.manytoone;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.beanvalidation.ValidationMode;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-13959")
|
||||
public class NotNullManyToOneTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
configuration.setProperty( AvailableSettings.JPA_VALIDATION_MODE, ValidationMode.AUTO.name() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSave() {
|
||||
inTransaction(
|
||||
session -> {
|
||||
Parent parent = new Parent( new Child() );
|
||||
session.save( parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test(expected = javax.validation.ConstraintViolationException.class)
|
||||
public void testSaveChildWithoutParent() {
|
||||
inTransaction(
|
||||
session -> {
|
||||
Child child = new Child();
|
||||
session.save( child );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
public static class Child {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
@ManyToOne
|
||||
private Parent parent;
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
public static class Parent {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(cascade = CascadeType.ALL)
|
||||
private Child child;
|
||||
|
||||
public Parent(Child child) {
|
||||
this.child = child;
|
||||
this.child.setParent( this );
|
||||
}
|
||||
|
||||
public Child getChild() {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue