Move annotations.immutable tests and implement immutable update warning/error
This commit is contained in:
parent
eaba3acc20
commit
f84585c5ed
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.query.sqm.internal;
|
package org.hibernate.query.sqm.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,6 +33,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.collections.IdentitySet;
|
import org.hibernate.internal.util.collections.IdentitySet;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Loadable;
|
import org.hibernate.persister.entity.Loadable;
|
||||||
|
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||||
import org.hibernate.query.Query;
|
import org.hibernate.query.Query;
|
||||||
import org.hibernate.query.QueryTypeMismatchException;
|
import org.hibernate.query.QueryTypeMismatchException;
|
||||||
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
|
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
|
||||||
|
@ -128,6 +130,9 @@ public class QuerySqmImpl<R>
|
||||||
throw new IllegalArgumentException( "Non-select queries cannot be typed" );
|
throw new IllegalArgumentException( "Non-select queries cannot be typed" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( sqmStatement instanceof SqmUpdateStatement<?> ) {
|
||||||
|
verifyImmutableEntityUpdate( hqlString, (SqmUpdateStatement<R>) sqmStatement, producer.getFactory() );
|
||||||
|
}
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
this.domainParameterXref = hqlInterpretation.getDomainParameterXref();
|
this.domainParameterXref = hqlInterpretation.getDomainParameterXref();
|
||||||
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
|
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
|
||||||
|
@ -182,6 +187,9 @@ public class QuerySqmImpl<R>
|
||||||
producer.getFactory()
|
producer.getFactory()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if ( sqmStatement instanceof SqmUpdateStatement<?> ) {
|
||||||
|
verifyImmutableEntityUpdate( hqlString, (SqmUpdateStatement<R>) sqmStatement, producer.getFactory() );
|
||||||
|
}
|
||||||
|
|
||||||
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
|
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
|
||||||
this.domainParameterXref = hqlInterpretation.getDomainParameterXref();
|
this.domainParameterXref = hqlInterpretation.getDomainParameterXref();
|
||||||
|
@ -209,6 +217,9 @@ public class QuerySqmImpl<R>
|
||||||
producer.getFactory()
|
producer.getFactory()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if ( sqmStatement instanceof SqmUpdateStatement<?> ) {
|
||||||
|
verifyImmutableEntityUpdate( CRITERIA_HQL_STRING, (SqmUpdateStatement<R>) sqmStatement, producer.getFactory() );
|
||||||
|
}
|
||||||
|
|
||||||
this.hqlString = CRITERIA_HQL_STRING;
|
this.hqlString = CRITERIA_HQL_STRING;
|
||||||
this.sqmStatement = sqmStatement;
|
this.sqmStatement = sqmStatement;
|
||||||
|
@ -339,6 +350,37 @@ public class QuerySqmImpl<R>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyImmutableEntityUpdate(
|
||||||
|
String hqlString,
|
||||||
|
SqmUpdateStatement<R> sqmStatement,
|
||||||
|
SessionFactoryImplementor factory) {
|
||||||
|
final EntityPersister entityDescriptor = factory.getDomainModel()
|
||||||
|
.getEntityDescriptor( sqmStatement.getTarget().getEntityName() );
|
||||||
|
if ( entityDescriptor.isMutable() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ImmutableEntityUpdateQueryHandlingMode immutableEntityUpdateQueryHandlingMode = factory
|
||||||
|
.getSessionFactoryOptions()
|
||||||
|
.getImmutableEntityUpdateQueryHandlingMode();
|
||||||
|
|
||||||
|
String querySpaces = Arrays.toString( entityDescriptor.getQuerySpaces() );
|
||||||
|
|
||||||
|
switch ( immutableEntityUpdateQueryHandlingMode ) {
|
||||||
|
case WARNING:
|
||||||
|
LOG.immutableEntityUpdateQuery( hqlString, querySpaces );
|
||||||
|
break;
|
||||||
|
case EXCEPTION:
|
||||||
|
throw new HibernateException(
|
||||||
|
"The query: [" + hqlString + "] attempts to update an immutable entity: " + querySpaces
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"The " + immutableEntityUpdateQueryHandlingMode + " is not supported!"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SessionFactoryImplementor getSessionFactory() {
|
public SessionFactoryImplementor getSessionFactory() {
|
||||||
return getSession().getFactory();
|
return getSession().getFactory();
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,9 +260,11 @@ import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||||
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
|
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
|
||||||
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
|
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
|
||||||
import org.hibernate.sql.ast.tree.from.CorrelatedTableGroup;
|
import org.hibernate.sql.ast.tree.from.CorrelatedTableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.from.LazyTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
|
import org.hibernate.sql.ast.tree.from.VirtualTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.insert.InsertStatement;
|
import org.hibernate.sql.ast.tree.insert.InsertStatement;
|
||||||
import org.hibernate.sql.ast.tree.insert.Values;
|
import org.hibernate.sql.ast.tree.insert.Values;
|
||||||
import org.hibernate.sql.ast.tree.predicate.BetweenPredicate;
|
import org.hibernate.sql.ast.tree.predicate.BetweenPredicate;
|
||||||
|
@ -662,9 +664,10 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
consumeReusablePaths( sqmPath, correspondingTableGroup, BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin );
|
consumeReusablePaths( sqmPath, correspondingTableGroup, BaseSqmToSqlAstConverter::verifyManipulationImplicitJoin );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyManipulationImplicitJoin(SqmPath<?> joinedPath) {
|
private static void verifyManipulationImplicitJoin(TableGroup tableGroup) {
|
||||||
//noinspection StatementWithEmptyBody
|
//noinspection StatementWithEmptyBody
|
||||||
if ( joinedPath instanceof SqmEmbeddedValuedSimplePath<?> ) {
|
if ( tableGroup instanceof LazyTableGroup && ( (LazyTableGroup) tableGroup ).getUnderlyingTableGroup() == null
|
||||||
|
|| tableGroup instanceof VirtualTableGroup ) {
|
||||||
// this is fine
|
// this is fine
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2155,13 +2158,13 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
private void consumeReusablePaths(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
private void consumeReusablePaths(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
||||||
consumeReusablePaths( sqmPath, tableGroup, (sqmSubPath) -> {} );
|
consumeReusablePaths( sqmPath, tableGroup, tg -> {} );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void consumeReusablePaths(
|
private void consumeReusablePaths(
|
||||||
SqmPath<?> sqmPath,
|
SqmPath<?> sqmPath,
|
||||||
TableGroup parentTableGroup,
|
TableGroup parentTableGroup,
|
||||||
Consumer<SqmPath<?>> implicitJoinChecker) {
|
Consumer<TableGroup> implicitJoinChecker) {
|
||||||
if ( log.isTraceEnabled() ) {
|
if ( log.isTraceEnabled() ) {
|
||||||
log.tracef( "Visiting implicit joins for `%s`", sqmPath.getNavigablePath() );
|
log.tracef( "Visiting implicit joins for `%s`", sqmPath.getNavigablePath() );
|
||||||
}
|
}
|
||||||
|
@ -2187,7 +2190,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
final TableGroup tableGroup;
|
final TableGroup tableGroup;
|
||||||
if ( subPart instanceof TableGroupJoinProducer ) {
|
if ( subPart instanceof TableGroupJoinProducer ) {
|
||||||
implicitJoinChecker.accept( joinedPath );
|
|
||||||
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
|
final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) subPart;
|
||||||
final SqlAstJoinType defaultSqlAstJoinType = joinProducer.getDefaultSqlAstJoinType(
|
final SqlAstJoinType defaultSqlAstJoinType = joinProducer.getDefaultSqlAstJoinType(
|
||||||
parentTableGroup );
|
parentTableGroup );
|
||||||
|
@ -2207,6 +2209,9 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
tableGroup = null;
|
tableGroup = null;
|
||||||
}
|
}
|
||||||
consumeReusablePaths( joinedPath, tableGroup, implicitJoinChecker );
|
consumeReusablePaths( joinedPath, tableGroup, implicitJoinChecker );
|
||||||
|
if ( tableGroup != null ) {
|
||||||
|
implicitJoinChecker.accept( tableGroup );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import org.hibernate.annotations.Immutable;
|
import org.hibernate.annotations.Immutable;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//$Id$
|
//$Id$
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// $Id$
|
// $Id$
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -122,12 +122,8 @@ public class ImmutableEntityUpdateQueryHandlingModeExceptionTest extends BaseNon
|
||||||
String statement = "Update ImmutableEntity e set e.selector = :changeable where e.id in " +
|
String statement = "Update ImmutableEntity e set e.selector = :changeable where e.id in " +
|
||||||
"(select i.id from MutableEntity i where i.changeable = :selector)";
|
"(select i.id from MutableEntity i where i.changeable = :selector)";
|
||||||
|
|
||||||
Query query = session.createQuery(statement);
|
|
||||||
query.setParameter("changeable", "end");
|
|
||||||
query.setParameter("selector", "foo");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
query.executeUpdate();
|
session.createQuery(statement);
|
||||||
|
|
||||||
fail("Should have throw exception");
|
fail("Should have throw exception");
|
||||||
}
|
}
|
|
@ -4,10 +4,10 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.SessionImpl;
|
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
@ -30,7 +30,7 @@ public class ImmutableEntityUpdateQueryHandlingModeWarningTest extends BaseNonCo
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
|
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
|
||||||
Logger.getMessageLogger( CoreMessageLogger.class, SessionImpl.class.getName() ) );
|
Logger.getMessageLogger( CoreMessageLogger.class, QuerySqmImpl.class.getName() ) );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class[] getAnnotatedClasses() {
|
protected Class[] getAnnotatedClasses() {
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -22,8 +22,6 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import javax.persistence.Convert;
|
import javax.persistence.Convert;
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// $Id$
|
// $Id$
|
||||||
package org.hibernate.test.annotations.immutable;
|
package org.hibernate.orm.test.annotations.immutable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
Loading…
Reference in New Issue