* Added JpaCompliance for @OrderBy handling
* Added `NonTransientException` checked during MappingModelCreationProcess "post init callback" handling to indicate non-recoverable errors * Redesigned `MappingModelCreationProcess#executePostInitCallbacks` to account for `NonTransientException`
This commit is contained in:
parent
d180cb63d2
commit
41093ae66c
|
@ -102,4 +102,8 @@
|
||||||
|90005700
|
|90005700
|
||||||
|org.hibernate.envers.boot.EnversBootLogger
|
|org.hibernate.envers.boot.EnversBootLogger
|
||||||
|
|
||||||
|
|90005701
|
||||||
|
|90005800
|
||||||
|
|org.hibernate.metamodel.mapping.MappingModelCreationLogger
|
||||||
|
|
||||||
|===
|
|===
|
||||||
|
|
|
@ -728,6 +728,11 @@ public interface SessionFactoryBuilder {
|
||||||
*/
|
*/
|
||||||
SessionFactoryBuilder enableJpaQueryCompliance(boolean enabled);
|
SessionFactoryBuilder enableJpaQueryCompliance(boolean enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see JpaCompliance#isJpaQueryComplianceEnabled()
|
||||||
|
*/
|
||||||
|
SessionFactoryBuilder enableJpaOrderByMappingCompliance(boolean enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see JpaCompliance#isJpaTransactionComplianceEnabled()
|
* @see JpaCompliance#isJpaTransactionComplianceEnabled()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -416,6 +416,12 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SessionFactoryBuilder enableJpaOrderByMappingCompliance(boolean enabled) {
|
||||||
|
this.optionsBuilder.enableJpaOrderByMappingCompliance( enabled );
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
|
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
|
||||||
this.optionsBuilder.enableJpaTransactionCompliance( enabled );
|
this.optionsBuilder.enableJpaTransactionCompliance( enabled );
|
||||||
|
|
|
@ -1478,6 +1478,14 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
mutableJpaCompliance().setCachingCompliance( enabled );
|
mutableJpaCompliance().setCachingCompliance( enabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void enableJpaOrderByMappingCompliance(boolean enabled) {
|
||||||
|
mutableJpaCompliance().setOrderByMappingCompliance( enabled );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableGeneratorNameScopeCompliance(boolean enabled) {
|
||||||
|
mutableJpaCompliance().setGeneratorNameScopeCompliance( enabled );
|
||||||
|
}
|
||||||
|
|
||||||
public void disableRefreshDetachedEntity() {
|
public void disableRefreshDetachedEntity() {
|
||||||
this.allowRefreshDetachedEntity = false;
|
this.allowRefreshDetachedEntity = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,6 +394,12 @@ public abstract class AbstractDelegatingSessionFactoryBuilder<T extends SessionF
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SessionFactoryBuilder enableJpaOrderByMappingCompliance(boolean enabled) {
|
||||||
|
delegate.enableJpaOrderByMappingCompliance( enabled );
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
|
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
|
||||||
delegate.enableJpaTransactionCompliance( enabled );
|
delegate.enableJpaTransactionCompliance( enabled );
|
||||||
|
|
|
@ -2006,6 +2006,19 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
*/
|
*/
|
||||||
String JPA_LIST_COMPLIANCE = "hibernate.jpa.compliance.list";
|
String JPA_LIST_COMPLIANCE = "hibernate.jpa.compliance.list";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether Hibernate should recognize what it considers a "bag"
|
||||||
|
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List
|
||||||
|
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag.
|
||||||
|
*
|
||||||
|
* If enabled, we will recognize it as a List where {@link javax.persistence.OrderColumn}
|
||||||
|
* is just missing (and its defaults will apply).
|
||||||
|
*
|
||||||
|
* @see JpaCompliance#isJpaOrderByMappingComplianceEnabled() ()
|
||||||
|
* @since 6.0
|
||||||
|
*/
|
||||||
|
String JPA_ORDER_BY_MAPPING_COMPLIANCE = "hibernate.jpa.compliance.orderby";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA defines specific exceptions on specific methods when called on
|
* JPA defines specific exceptions on specific methods when called on
|
||||||
* {@link javax.persistence.EntityManager} and {@link javax.persistence.EntityManagerFactory}
|
* {@link javax.persistence.EntityManager} and {@link javax.persistence.EntityManagerFactory}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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.jpa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contract for exceptions describing JPA compliance violations
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface JpaComplianceViolation {
|
||||||
|
}
|
|
@ -12,22 +12,24 @@ import org.hibernate.jpa.spi.JpaCompliance;
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
public class JpaComplianceImpl implements JpaCompliance {
|
public class JpaComplianceImpl implements JpaCompliance {
|
||||||
private boolean queryCompliance;
|
private final boolean listCompliance;
|
||||||
private boolean transactionCompliance;
|
private final boolean orderByMappingCompliance;
|
||||||
private boolean listCompliance;
|
private final boolean proxyCompliance;
|
||||||
private boolean closedCompliance;
|
private final boolean globalGeneratorNameScopeCompliance;
|
||||||
private boolean proxyCompliance;
|
private final boolean queryCompliance;
|
||||||
private boolean cachingCompliance;
|
private final boolean transactionCompliance;
|
||||||
private boolean globalGeneratorNameScopeCompliance;
|
private final boolean closedCompliance;
|
||||||
|
private final boolean cachingCompliance;
|
||||||
|
|
||||||
private JpaComplianceImpl(
|
private JpaComplianceImpl(
|
||||||
|
boolean listCompliance,
|
||||||
|
boolean orderByMappingCompliance,
|
||||||
|
boolean proxyCompliance,
|
||||||
|
boolean globalGeneratorNameScopeCompliance,
|
||||||
boolean queryCompliance,
|
boolean queryCompliance,
|
||||||
boolean transactionCompliance,
|
boolean transactionCompliance,
|
||||||
boolean listCompliance,
|
|
||||||
boolean closedCompliance,
|
boolean closedCompliance,
|
||||||
boolean proxyCompliance,
|
boolean cachingCompliance) {
|
||||||
boolean cachingCompliance,
|
|
||||||
boolean globalGeneratorNameScopeCompliance) {
|
|
||||||
this.queryCompliance = queryCompliance;
|
this.queryCompliance = queryCompliance;
|
||||||
this.transactionCompliance = transactionCompliance;
|
this.transactionCompliance = transactionCompliance;
|
||||||
this.listCompliance = listCompliance;
|
this.listCompliance = listCompliance;
|
||||||
|
@ -35,6 +37,7 @@ public class JpaComplianceImpl implements JpaCompliance {
|
||||||
this.proxyCompliance = proxyCompliance;
|
this.proxyCompliance = proxyCompliance;
|
||||||
this.cachingCompliance = cachingCompliance;
|
this.cachingCompliance = cachingCompliance;
|
||||||
this.globalGeneratorNameScopeCompliance = globalGeneratorNameScopeCompliance;
|
this.globalGeneratorNameScopeCompliance = globalGeneratorNameScopeCompliance;
|
||||||
|
this.orderByMappingCompliance = orderByMappingCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,18 +75,39 @@ public class JpaComplianceImpl implements JpaCompliance {
|
||||||
return globalGeneratorNameScopeCompliance;
|
return globalGeneratorNameScopeCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaOrderByMappingComplianceEnabled() {
|
||||||
|
return orderByMappingCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
public static class JpaComplianceBuilder {
|
public static class JpaComplianceBuilder {
|
||||||
private boolean queryCompliance;
|
private boolean queryCompliance;
|
||||||
private boolean transactionCompliance;
|
|
||||||
private boolean listCompliance;
|
private boolean listCompliance;
|
||||||
private boolean closedCompliance;
|
private boolean orderByMappingCompliance;
|
||||||
private boolean proxyCompliance;
|
private boolean proxyCompliance;
|
||||||
private boolean cachingCompliance;
|
|
||||||
private boolean globalGeneratorNameScopeCompliance;
|
private boolean globalGeneratorNameScopeCompliance;
|
||||||
|
private boolean cachingCompliance;
|
||||||
|
private boolean transactionCompliance;
|
||||||
|
private boolean closedCompliance;
|
||||||
|
|
||||||
public JpaComplianceBuilder() {
|
public JpaComplianceBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JpaComplianceBuilder setListCompliance(boolean listCompliance) {
|
||||||
|
this.listCompliance = listCompliance;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JpaComplianceBuilder setOrderByMappingCompliance(boolean orderByMappingCompliance) {
|
||||||
|
this.orderByMappingCompliance = orderByMappingCompliance;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JpaComplianceBuilder setProxyCompliance(boolean proxyCompliance) {
|
||||||
|
this.proxyCompliance = proxyCompliance;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public JpaComplianceBuilder setQueryCompliance(boolean queryCompliance) {
|
public JpaComplianceBuilder setQueryCompliance(boolean queryCompliance) {
|
||||||
this.queryCompliance = queryCompliance;
|
this.queryCompliance = queryCompliance;
|
||||||
return this;
|
return this;
|
||||||
|
@ -94,21 +118,11 @@ public class JpaComplianceImpl implements JpaCompliance {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaComplianceBuilder setListCompliance(boolean listCompliance) {
|
|
||||||
this.listCompliance = listCompliance;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JpaComplianceBuilder setClosedCompliance(boolean closedCompliance) {
|
public JpaComplianceBuilder setClosedCompliance(boolean closedCompliance) {
|
||||||
this.closedCompliance = closedCompliance;
|
this.closedCompliance = closedCompliance;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JpaComplianceBuilder setProxyCompliance(boolean proxyCompliance) {
|
|
||||||
this.proxyCompliance = proxyCompliance;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JpaComplianceBuilder setCachingCompliance(boolean cachingCompliance) {
|
public JpaComplianceBuilder setCachingCompliance(boolean cachingCompliance) {
|
||||||
this.cachingCompliance = cachingCompliance;
|
this.cachingCompliance = cachingCompliance;
|
||||||
return this;
|
return this;
|
||||||
|
@ -121,13 +135,14 @@ public class JpaComplianceImpl implements JpaCompliance {
|
||||||
|
|
||||||
JpaCompliance createJpaCompliance() {
|
JpaCompliance createJpaCompliance() {
|
||||||
return new JpaComplianceImpl(
|
return new JpaComplianceImpl(
|
||||||
|
listCompliance,
|
||||||
|
orderByMappingCompliance,
|
||||||
|
proxyCompliance,
|
||||||
|
globalGeneratorNameScopeCompliance,
|
||||||
queryCompliance,
|
queryCompliance,
|
||||||
transactionCompliance,
|
transactionCompliance,
|
||||||
listCompliance,
|
|
||||||
closedCompliance,
|
closedCompliance,
|
||||||
proxyCompliance,
|
cachingCompliance
|
||||||
cachingCompliance,
|
|
||||||
globalGeneratorNameScopeCompliance
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,50 +17,60 @@ import org.hibernate.jpa.spi.MutableJpaCompliance;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class MutableJpaComplianceImpl implements MutableJpaCompliance {
|
public class MutableJpaComplianceImpl implements MutableJpaCompliance {
|
||||||
|
private boolean listCompliance;
|
||||||
|
private boolean orderByMappingCompliance;
|
||||||
|
private boolean proxyCompliance;
|
||||||
|
private boolean generatorNameScopeCompliance;
|
||||||
private boolean queryCompliance;
|
private boolean queryCompliance;
|
||||||
private boolean transactionCompliance;
|
private boolean transactionCompliance;
|
||||||
private boolean listCompliance;
|
|
||||||
private boolean closedCompliance;
|
private boolean closedCompliance;
|
||||||
private boolean proxyCompliance;
|
|
||||||
private boolean cachingCompliance;
|
private boolean cachingCompliance;
|
||||||
private final boolean globalGeneratorNameScopeCompliance;
|
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
public MutableJpaComplianceImpl(Map configurationSettings, boolean jpaByDefault) {
|
public MutableJpaComplianceImpl(Map configurationSettings, boolean jpaByDefault) {
|
||||||
final Object legacyQueryCompliance = configurationSettings.get( AvailableSettings.JPAQL_STRICT_COMPLIANCE );
|
final Object legacyQueryCompliance = configurationSettings.get( AvailableSettings.JPAQL_STRICT_COMPLIANCE );
|
||||||
|
|
||||||
queryCompliance = ConfigurationHelper.getBoolean(
|
|
||||||
AvailableSettings.JPA_QUERY_COMPLIANCE,
|
|
||||||
configurationSettings,
|
|
||||||
ConfigurationHelper.toBoolean( legacyQueryCompliance, jpaByDefault )
|
|
||||||
);
|
|
||||||
transactionCompliance = ConfigurationHelper.getBoolean(
|
|
||||||
AvailableSettings.JPA_TRANSACTION_COMPLIANCE,
|
|
||||||
configurationSettings,
|
|
||||||
jpaByDefault
|
|
||||||
);
|
|
||||||
listCompliance = ConfigurationHelper.getBoolean(
|
listCompliance = ConfigurationHelper.getBoolean(
|
||||||
AvailableSettings.JPA_LIST_COMPLIANCE,
|
AvailableSettings.JPA_LIST_COMPLIANCE,
|
||||||
configurationSettings,
|
configurationSettings,
|
||||||
jpaByDefault
|
jpaByDefault
|
||||||
);
|
);
|
||||||
closedCompliance = ConfigurationHelper.getBoolean(
|
|
||||||
AvailableSettings.JPA_CLOSED_COMPLIANCE,
|
|
||||||
configurationSettings,
|
|
||||||
jpaByDefault
|
|
||||||
);
|
|
||||||
proxyCompliance = ConfigurationHelper.getBoolean(
|
proxyCompliance = ConfigurationHelper.getBoolean(
|
||||||
AvailableSettings.JPA_PROXY_COMPLIANCE,
|
AvailableSettings.JPA_PROXY_COMPLIANCE,
|
||||||
configurationSettings,
|
configurationSettings,
|
||||||
jpaByDefault
|
jpaByDefault
|
||||||
);
|
);
|
||||||
cachingCompliance = ConfigurationHelper.getBoolean(
|
generatorNameScopeCompliance = ConfigurationHelper.getBoolean(
|
||||||
AvailableSettings.JPA_CACHING_COMPLIANCE,
|
AvailableSettings.JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE,
|
||||||
configurationSettings,
|
configurationSettings,
|
||||||
jpaByDefault
|
jpaByDefault
|
||||||
);
|
);
|
||||||
globalGeneratorNameScopeCompliance = ConfigurationHelper.getBoolean(
|
orderByMappingCompliance = ConfigurationHelper.getBoolean(
|
||||||
AvailableSettings.JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE,
|
AvailableSettings.JPA_ORDER_BY_MAPPING_COMPLIANCE,
|
||||||
|
configurationSettings,
|
||||||
|
jpaByDefault
|
||||||
|
);
|
||||||
|
|
||||||
|
queryCompliance = ConfigurationHelper.getBoolean(
|
||||||
|
AvailableSettings.JPA_QUERY_COMPLIANCE,
|
||||||
|
configurationSettings,
|
||||||
|
ConfigurationHelper.toBoolean( legacyQueryCompliance, jpaByDefault )
|
||||||
|
);
|
||||||
|
|
||||||
|
transactionCompliance = ConfigurationHelper.getBoolean(
|
||||||
|
AvailableSettings.JPA_TRANSACTION_COMPLIANCE,
|
||||||
|
configurationSettings,
|
||||||
|
jpaByDefault
|
||||||
|
);
|
||||||
|
|
||||||
|
closedCompliance = ConfigurationHelper.getBoolean(
|
||||||
|
AvailableSettings.JPA_CLOSED_COMPLIANCE,
|
||||||
|
configurationSettings,
|
||||||
|
jpaByDefault
|
||||||
|
);
|
||||||
|
|
||||||
|
cachingCompliance = ConfigurationHelper.getBoolean(
|
||||||
|
AvailableSettings.JPA_CACHING_COMPLIANCE,
|
||||||
configurationSettings,
|
configurationSettings,
|
||||||
jpaByDefault
|
jpaByDefault
|
||||||
);
|
);
|
||||||
|
@ -98,46 +108,69 @@ public class MutableJpaComplianceImpl implements MutableJpaCompliance {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGlobalGeneratorScopeEnabled() {
|
public boolean isGlobalGeneratorScopeEnabled() {
|
||||||
return globalGeneratorNameScopeCompliance;
|
return generatorNameScopeCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaOrderByMappingComplianceEnabled() {
|
||||||
|
return orderByMappingCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Mutators
|
// Mutators
|
||||||
|
|
||||||
public void setQueryCompliance(boolean queryCompliance) {
|
@Override
|
||||||
this.queryCompliance = queryCompliance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionCompliance(boolean transactionCompliance) {
|
|
||||||
this.transactionCompliance = transactionCompliance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setListCompliance(boolean listCompliance) {
|
public void setListCompliance(boolean listCompliance) {
|
||||||
this.listCompliance = listCompliance;
|
this.listCompliance = listCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClosedCompliance(boolean closedCompliance) {
|
@Override
|
||||||
this.closedCompliance = closedCompliance;
|
public void setOrderByMappingCompliance(boolean orderByMappingCompliance) {
|
||||||
|
this.orderByMappingCompliance = orderByMappingCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setProxyCompliance(boolean proxyCompliance) {
|
public void setProxyCompliance(boolean proxyCompliance) {
|
||||||
this.proxyCompliance = proxyCompliance;
|
this.proxyCompliance = proxyCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGeneratorNameScopeCompliance(boolean enabled) {
|
||||||
|
this.generatorNameScopeCompliance = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryCompliance(boolean queryCompliance) {
|
||||||
|
this.queryCompliance = queryCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransactionCompliance(boolean transactionCompliance) {
|
||||||
|
this.transactionCompliance = transactionCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClosedCompliance(boolean closedCompliance) {
|
||||||
|
this.closedCompliance = closedCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setCachingCompliance(boolean cachingCompliance) {
|
public void setCachingCompliance(boolean cachingCompliance) {
|
||||||
this.cachingCompliance = cachingCompliance;
|
this.cachingCompliance = cachingCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JpaCompliance immutableCopy() {
|
public JpaCompliance immutableCopy() {
|
||||||
JpaComplianceImpl.JpaComplianceBuilder builder = new JpaComplianceImpl.JpaComplianceBuilder();
|
JpaComplianceImpl.JpaComplianceBuilder builder = new JpaComplianceImpl.JpaComplianceBuilder();
|
||||||
builder.setQueryCompliance( queryCompliance )
|
builder = builder.setListCompliance( listCompliance )
|
||||||
.setTransactionCompliance( transactionCompliance )
|
|
||||||
.setListCompliance( listCompliance )
|
|
||||||
.setClosedCompliance( closedCompliance )
|
|
||||||
.setProxyCompliance( proxyCompliance )
|
.setProxyCompliance( proxyCompliance )
|
||||||
.setCachingCompliance( cachingCompliance )
|
.setOrderByMappingCompliance( orderByMappingCompliance )
|
||||||
.setGlobalGeneratorNameCompliance( globalGeneratorNameScopeCompliance );
|
.setGlobalGeneratorNameCompliance( generatorNameScopeCompliance )
|
||||||
|
.setQueryCompliance( queryCompliance )
|
||||||
|
.setTransactionCompliance( transactionCompliance )
|
||||||
|
.setClosedCompliance( closedCompliance )
|
||||||
|
.setCachingCompliance( cachingCompliance );
|
||||||
return builder.createJpaCompliance();
|
return builder.createJpaCompliance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,4 +97,12 @@ public interface JpaCompliance {
|
||||||
* @return {@code true} indicates the generator name scope is considered global.
|
* @return {@code true} indicates the generator name scope is considered global.
|
||||||
*/
|
*/
|
||||||
boolean isGlobalGeneratorScopeEnabled();
|
boolean isGlobalGeneratorScopeEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we strictly handle {@link javax.persistence.OrderBy} expressions?
|
||||||
|
*
|
||||||
|
* JPA says the order-items can only be attribute references whereas Hibernate supports a wide range of items. With
|
||||||
|
* this enabled, Hibernate will throw a compliance error when a non-attribute-reference is used.
|
||||||
|
*/
|
||||||
|
boolean isJpaOrderByMappingComplianceEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,21 @@ package org.hibernate.jpa.spi;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface MutableJpaCompliance extends JpaCompliance {
|
public interface MutableJpaCompliance extends JpaCompliance {
|
||||||
|
void setListCompliance(boolean listCompliance);
|
||||||
|
|
||||||
|
void setOrderByMappingCompliance(boolean orderByCompliance);
|
||||||
|
|
||||||
|
void setProxyCompliance(boolean proxyCompliance);
|
||||||
|
|
||||||
void setQueryCompliance(boolean queryCompliance);
|
void setQueryCompliance(boolean queryCompliance);
|
||||||
|
|
||||||
void setTransactionCompliance(boolean transactionCompliance);
|
void setTransactionCompliance(boolean transactionCompliance);
|
||||||
|
|
||||||
void setListCompliance(boolean listCompliance);
|
|
||||||
|
|
||||||
void setClosedCompliance(boolean closedCompliance);
|
void setClosedCompliance(boolean closedCompliance);
|
||||||
|
|
||||||
void setProxyCompliance(boolean proxyCompliance);
|
|
||||||
|
|
||||||
void setCachingCompliance(boolean cachingCompliance);
|
void setCachingCompliance(boolean cachingCompliance);
|
||||||
|
|
||||||
|
void setGeneratorNameScopeCompliance(boolean generatorScopeCompliance);
|
||||||
|
|
||||||
JpaCompliance immutableCopy();
|
JpaCompliance immutableCopy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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.metamodel.mapping;
|
||||||
|
|
||||||
|
import org.hibernate.query.QueryLogger;
|
||||||
|
|
||||||
|
import org.jboss.logging.BasicLogger;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.logging.annotations.MessageLogger;
|
||||||
|
import org.jboss.logging.annotations.ValidIdRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger used during mapping-model creation
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@MessageLogger( projectCode = "HHH" )
|
||||||
|
@ValidIdRange( min = 90005701, max = 90005800 )
|
||||||
|
public interface MappingModelCreationLogger extends BasicLogger {
|
||||||
|
String LOGGER_NAME = "org.hibernate.orm.model.mapping.creation";
|
||||||
|
|
||||||
|
MappingModelCreationLogger LOGGER = Logger.getMessageLogger( MappingModelCreationLogger.class, LOGGER_NAME );
|
||||||
|
|
||||||
|
boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
|
||||||
|
boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* 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.metamodel.mapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker interface for exceptions thrown during mapping-model creation which
|
||||||
|
* are not transient errors - they will never succeed
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface NonTransientException {
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.NonTransientException;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||||
|
@ -793,7 +794,11 @@ public class MappingModelCreationHelper {
|
||||||
catch (NotYetImplementedFor6Exception nye) {
|
catch (NotYetImplementedFor6Exception nye) {
|
||||||
throw nye;
|
throw nye;
|
||||||
}
|
}
|
||||||
catch (Exception wait) {
|
catch (Exception e) {
|
||||||
|
if ( e instanceof NonTransientException ) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelCreationLogger;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.NonTransientException;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
@ -69,25 +71,40 @@ public class MappingModelCreationProcess {
|
||||||
entityPersister.prepareMappingModel( this );
|
entityPersister.prepareMappingModel( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
executePostInitCallbakcs( postInitCallbacks );
|
MappingModelCreationLogger.LOGGER.debugf( "Starting generic post-init callbacks" );
|
||||||
|
executePostInitCallbacks( postInitCallbacks );
|
||||||
|
|
||||||
executePostInitCallbakcs( foreignKeyPostInitCallbacks );
|
MappingModelCreationLogger.LOGGER.debugf( "Starting foreign-key post-init callbacks" );
|
||||||
|
executePostInitCallbacks( foreignKeyPostInitCallbacks );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executePostInitCallbakcs(List<PostInitCallback> postInitCallbacks) {
|
private void executePostInitCallbacks(List<PostInitCallback> postInitCallbacks) {
|
||||||
while ( postInitCallbacks != null && !postInitCallbacks.isEmpty() ) {
|
while ( postInitCallbacks != null && !postInitCallbacks.isEmpty() ) {
|
||||||
// copy to avoid CCME
|
|
||||||
final ArrayList<PostInitCallback> copy = new ArrayList<>( new ArrayList<>( postInitCallbacks ) );
|
|
||||||
|
|
||||||
for ( PostInitCallback callback : copy ) {
|
// copy to avoid CCME
|
||||||
|
final ArrayList<PostInitCallback> copy = new ArrayList<>( postInitCallbacks );
|
||||||
|
|
||||||
|
for ( int i = 0; i < copy.size(); i++ ) {
|
||||||
|
final PostInitCallback callback = copy.get( i );
|
||||||
|
|
||||||
|
try {
|
||||||
final boolean completed = callback.process();
|
final boolean completed = callback.process();
|
||||||
if ( completed ) {
|
if ( completed ) {
|
||||||
postInitCallbacks.remove( callback );
|
postInitCallbacks.remove( callback );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if ( e instanceof NonTransientException ) {
|
||||||
|
MappingModelCreationLogger.LOGGER.debugf( "Mapping-model creation encountered non-transient error : %s", e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
MappingModelCreationLogger.LOGGER.debugf( "Mapping-model creation encountered (possibly) transient error : %s", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( copy.size() == postInitCallbacks.size() ) {
|
if ( copy.size() == postInitCallbacks.size() ) {
|
||||||
// none of the processes could complete fully, this is an error
|
// none of the remaining callbacks could complete fully, this is an error
|
||||||
throw new IllegalStateException( "No post-init callbacks could complete" );
|
throw new IllegalStateException( "No post-init callbacks could complete" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.engine.FetchStrategy;
|
||||||
import org.hibernate.engine.FetchTiming;
|
import org.hibernate.engine.FetchTiming;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
|
import org.hibernate.jpa.spi.JpaCompliance;
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
import org.hibernate.mapping.IndexedCollection;
|
import org.hibernate.mapping.IndexedCollection;
|
||||||
import org.hibernate.mapping.List;
|
import org.hibernate.mapping.List;
|
||||||
|
@ -246,6 +247,10 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
||||||
|
|
||||||
if ( hasOrder || hasManyToManyOrder ) {
|
if ( hasOrder || hasManyToManyOrder ) {
|
||||||
final TranslationContext context = new TranslationContext() {
|
final TranslationContext context = new TranslationContext() {
|
||||||
|
@Override
|
||||||
|
public JpaCompliance getJpaCompliance() {
|
||||||
|
return collectionDescriptor.getFactory().getSessionFactoryOptions().getJpaCompliance();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( hasOrder ) {
|
if ( hasOrder ) {
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.mapping.ordering;
|
package org.hibernate.metamodel.mapping.ordering;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.spi.JpaCompliance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to information needed while translating a collection's order-by fragment
|
* Access to information needed while translating a collection's order-by fragment
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface TranslationContext {
|
public interface TranslationContext {
|
||||||
|
JpaCompliance getJpaCompliance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.metamodel.mapping.ordering.ast;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.jpa.JpaComplianceViolation;
|
||||||
|
import org.hibernate.metamodel.mapping.NonTransientException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class OrderByComplianceViolation extends HibernateException implements JpaComplianceViolation, NonTransientException {
|
||||||
|
public OrderByComplianceViolation(String message) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderByComplianceViolation(String message, Throwable cause) {
|
||||||
|
super( message, cause );
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,16 +17,12 @@ import org.hibernate.grammars.ordering.OrderingParserBaseVisitor;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
|
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ParseTreeVisitor extends OrderingParserBaseVisitor {
|
public class ParseTreeVisitor extends OrderingParserBaseVisitor<Object> {
|
||||||
private static final Logger log = Logger.getLogger( ParseTreeVisitor.class );
|
|
||||||
|
|
||||||
private final PathConsumer pathConsumer;
|
private final PathConsumer pathConsumer;
|
||||||
private final TranslationContext translationContext;
|
private final TranslationContext translationContext;
|
||||||
|
|
||||||
|
@ -60,7 +56,21 @@ public class ParseTreeVisitor extends OrderingParserBaseVisitor {
|
||||||
assert parsedSpec != null;
|
assert parsedSpec != null;
|
||||||
assert parsedSpec.expression() != null;
|
assert parsedSpec.expression() != null;
|
||||||
|
|
||||||
final OrderingSpecification result = new OrderingSpecification( visitExpression( parsedSpec.expression() ) );
|
final OrderingExpression orderingExpression = visitExpression( parsedSpec.expression() );
|
||||||
|
if ( translationContext.getJpaCompliance().isJpaOrderByMappingComplianceEnabled() ) {
|
||||||
|
if ( orderingExpression instanceof DomainPath ) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new OrderByComplianceViolation(
|
||||||
|
"`@OrderBy` expression (" + parsedSpec.expression().getText()
|
||||||
|
+ ") resolved to `" + orderingExpression
|
||||||
|
+ "` which is not a domain-model reference which violates the JPA specification"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final OrderingSpecification result = new OrderingSpecification( orderingExpression );
|
||||||
|
|
||||||
if ( parsedSpec.collationSpecification() != null ) {
|
if ( parsedSpec.collationSpecification() != null ) {
|
||||||
result.setCollation( parsedSpec.collationSpecification().identifier().getText() );
|
result.setCollation( parsedSpec.collationSpecification().identifier().getText() );
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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.jpa;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.spi.JpaCompliance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stubbed impl of JpaCompliance
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class JpaComplianceStub implements JpaCompliance {
|
||||||
|
@Override
|
||||||
|
public boolean isJpaQueryComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaTransactionComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaListComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaClosedComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaProxyComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaCacheComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGlobalGeneratorScopeEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaOrderByMappingComplianceEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ public class JpaComplianceTestingImpl implements JpaCompliance {
|
||||||
private boolean proxyCompliance;
|
private boolean proxyCompliance;
|
||||||
private boolean cacheCompliance;
|
private boolean cacheCompliance;
|
||||||
private boolean idGeneratorNameScopeCompliance;
|
private boolean idGeneratorNameScopeCompliance;
|
||||||
|
private boolean orderByCompliance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isJpaQueryComplianceEnabled() {
|
public boolean isJpaQueryComplianceEnabled() {
|
||||||
|
@ -63,6 +64,11 @@ public class JpaComplianceTestingImpl implements JpaCompliance {
|
||||||
return listCompliance;
|
return listCompliance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJpaOrderByMappingComplianceEnabled() {
|
||||||
|
return orderByCompliance;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isJpaClosedComplianceEnabled() {
|
public boolean isJpaClosedComplianceEnabled() {
|
||||||
return closedCompliance;
|
return closedCompliance;
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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.bootstrap.binding.annotations.plural.orderby.compliance;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.OrderBy;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.ordering.ast.OrderByComplianceViolation;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.transaction.TransactionUtil2;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class OrderByMappingComplianceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplianceChecking() {
|
||||||
|
check( false );
|
||||||
|
|
||||||
|
try {
|
||||||
|
check( true );
|
||||||
|
fail( "Expecting an exception" );
|
||||||
|
}
|
||||||
|
catch (OrderByComplianceViolation expected) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check(boolean complianceEnabled) {
|
||||||
|
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
|
||||||
|
.applySetting( AvailableSettings.HBM2DDL_AUTO, "create-drop" )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Metadata bootModel = new MetadataSources( ssr )
|
||||||
|
.addAnnotatedClass( Order.class )
|
||||||
|
.addAnnotatedClass( LineItem.class )
|
||||||
|
.buildMetadata();
|
||||||
|
|
||||||
|
final SessionFactory sf = bootModel.getSessionFactoryBuilder()
|
||||||
|
.enableJpaOrderByMappingCompliance( complianceEnabled )
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
TransactionUtil2.inTransaction(
|
||||||
|
(SessionFactoryImplementor) sf,
|
||||||
|
session -> session.createQuery( "from Order" ).list()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
sf.close();
|
||||||
|
}
|
||||||
|
catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
StandardServiceRegistryBuilder.destroy( ssr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "Order" )
|
||||||
|
@Table( name = "orders" )
|
||||||
|
public static class Order {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String invoice;
|
||||||
|
@OneToMany
|
||||||
|
@OrderBy( "qty" )
|
||||||
|
private Set<LineItem> lineItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "LineItem" )
|
||||||
|
@Table( name = "line_items" )
|
||||||
|
public static class LineItem {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String sku;
|
||||||
|
@Column( name = "qty" )
|
||||||
|
private int quantity;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue