HHH-16089 allow @Synchronize for a collection
This commit is contained in:
parent
803a9a0ffb
commit
0bb04b1021
|
@ -9,23 +9,28 @@ package org.hibernate.annotations;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Specifies the tables that hold state mapped by the annotated entity.
|
||||
* Specifies a table or tables that hold state mapped by the annotated
|
||||
* entity or collection.
|
||||
* <p>
|
||||
* If Hibernate is not aware that a certain table holds state mapped
|
||||
* by an entity class, then {@linkplain org.hibernate.FlushMode#AUTO
|
||||
* auto-flush} might not occur when it should, and queries against the
|
||||
* entity might return stale data.
|
||||
* by an entity class or collection, then modifications might not be
|
||||
* {@linkplain org.hibernate.FlushMode#AUTO automatically synchronized}
|
||||
* with the database before a query is executed against that table, and
|
||||
* the query might return stale data.
|
||||
* <p>
|
||||
* This annotation might be necessary if:
|
||||
* Ordinarily, Hibernate knows the tables containing the state of an
|
||||
* entity or collection. This annotation might be necessary if:
|
||||
* <ul>
|
||||
* <li>the entity maps a database view,
|
||||
* <li>the entity is persisted using handwritten SQL, that is, using
|
||||
* {@link SQLSelect @SQLSelect} and friends, or
|
||||
* <li>the entity is mapped using {@link Subselect @Subselect}.
|
||||
* <li>an entity or collection maps a database view,
|
||||
* <li>an entity or collection is persisted using handwritten SQL,
|
||||
* that is, using {@link SQLSelect @SQLSelect} and friends, or
|
||||
* <li>an entity is mapped using {@link Subselect @Subselect}.
|
||||
* </ul>
|
||||
* <p>
|
||||
* By default, the table names specified by this annotation are interpreted
|
||||
|
@ -39,7 +44,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
*
|
||||
* @see org.hibernate.query.SynchronizeableQuery
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Target({TYPE, FIELD, METHOD})
|
||||
@Retention(RUNTIME)
|
||||
public @interface Synchronize {
|
||||
/**
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.hibernate.annotations.SQLSelect;
|
|||
import org.hibernate.annotations.SQLUpdate;
|
||||
import org.hibernate.annotations.SortComparator;
|
||||
import org.hibernate.annotations.SortNatural;
|
||||
import org.hibernate.annotations.Synchronize;
|
||||
import org.hibernate.annotations.Where;
|
||||
import org.hibernate.annotations.WhereJoinTable;
|
||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
||||
|
@ -83,6 +84,7 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
|
|||
import org.hibernate.boot.spi.PropertyData;
|
||||
import org.hibernate.boot.spi.SecondPass;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.spi.FilterDefinition;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
@ -1642,6 +1644,7 @@ public abstract class CollectionBinder {
|
|||
LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() );
|
||||
}
|
||||
|
||||
bindSynchronize();
|
||||
bindFilters( false );
|
||||
handleWhere( false );
|
||||
|
||||
|
@ -1681,6 +1684,26 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private void bindSynchronize() {
|
||||
if ( property.isAnnotationPresent( Synchronize.class ) ) {
|
||||
final JdbcEnvironment jdbcEnvironment = buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment();
|
||||
final Synchronize synchronize = property.getAnnotation(Synchronize.class);
|
||||
for ( String table : synchronize.value() ) {
|
||||
String physicalName = synchronize.logical() ? toPhysicalName( jdbcEnvironment, table ) : table;
|
||||
collection.addSynchronizedTable( physicalName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String toPhysicalName(JdbcEnvironment jdbcEnvironment, String logicalName) {
|
||||
return buildingContext.getBuildingOptions().getPhysicalNamingStrategy()
|
||||
.toPhysicalTableName(
|
||||
jdbcEnvironment.getIdentifierHelper().toIdentifier( logicalName ),
|
||||
jdbcEnvironment
|
||||
)
|
||||
.render( jdbcEnvironment.getDialect() );
|
||||
}
|
||||
|
||||
private void bindFilters(boolean hasAssociationTable) {
|
||||
final Filter simpleFilter = property.getAnnotation( Filter.class );
|
||||
//set filtering
|
||||
|
@ -2084,6 +2107,8 @@ public abstract class CollectionBinder {
|
|||
else {
|
||||
handleOwnedManyToMany( targetEntity, isCollectionOfEntities );
|
||||
}
|
||||
|
||||
bindSynchronize();
|
||||
bindFilters( isCollectionOfEntities );
|
||||
handleWhere( isCollectionOfEntities );
|
||||
|
||||
|
|
|
@ -727,6 +727,10 @@ public abstract class Collection implements Fetchable, Value, Filterable {
|
|||
return synchronizedTables;
|
||||
}
|
||||
|
||||
public void addSynchronizedTable(String table) {
|
||||
synchronizedTables.add( table );
|
||||
}
|
||||
|
||||
public String getLoaderName() {
|
||||
return loaderName;
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ import org.hibernate.MappingException;
|
|||
* in a given set of named <em>query spaces</em>. A query space is usually, but not always,
|
||||
* a relational database table, in which case the name of the space is simply the table name.
|
||||
* <p>
|
||||
* Each {@linkplain jakarta.persistence.Entity entity type} is understood to store its state
|
||||
* in one or more query spaces. Usually, the query spaces are automatically determined by
|
||||
* the mapping, but sometimes they must be specified explicitly using
|
||||
* Each {@linkplain jakarta.persistence.Entity entity type} or collection is understood to
|
||||
* store its state in one or more query spaces. Usually, the query spaces are automatically
|
||||
* determined by the mapping, but sometimes they must be specified explicitly using
|
||||
* {@link org.hibernate.annotations.Synchronize @Synchronize}.
|
||||
* <p>
|
||||
* Query spaces mediate the interaction between query execution and synchronization of
|
||||
|
|
Loading…
Reference in New Issue