HHH-8246 Implement XML binding of NamedStoredProcedureQuery
This commit is contained in:
parent
ce77f15974
commit
a03d44f290
|
@ -272,7 +272,7 @@ public final class AnnotationBinder {
|
|||
(List<NamedStoredProcedureQuery>) defaults.get( NamedStoredProcedureQuery.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedStoredProcedureQuery annotation : annotations ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
|
||||
bindNamedStoredProcedureQuery( mappings, annotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -281,9 +281,7 @@ public final class AnnotationBinder {
|
|||
(List<NamedStoredProcedureQueries>) defaults.get( NamedStoredProcedureQueries.class );
|
||||
if ( annotations != null ) {
|
||||
for ( NamedStoredProcedureQueries annotation : annotations ) {
|
||||
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
|
||||
}
|
||||
bindNamedStoredProcedureQueries( mappings, annotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,24 +392,29 @@ public final class AnnotationBinder {
|
|||
}
|
||||
|
||||
// NamedStoredProcedureQuery handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{
|
||||
final NamedStoredProcedureQuery annotation = annotatedElement.getAnnotation( NamedStoredProcedureQuery.class );
|
||||
if ( annotation != null ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
|
||||
}
|
||||
}
|
||||
bindNamedStoredProcedureQuery( mappings, annotatedElement.getAnnotation( NamedStoredProcedureQuery.class ) );
|
||||
|
||||
// NamedStoredProcedureQueries handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{
|
||||
final NamedStoredProcedureQueries annotation = annotatedElement.getAnnotation( NamedStoredProcedureQueries.class );
|
||||
if ( annotation != null ) {
|
||||
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( queryAnnotation, mappings );
|
||||
}
|
||||
bindNamedStoredProcedureQueries(
|
||||
mappings,
|
||||
annotatedElement.getAnnotation( NamedStoredProcedureQueries.class )
|
||||
);
|
||||
}
|
||||
|
||||
private static void bindNamedStoredProcedureQueries(Mappings mappings, NamedStoredProcedureQueries annotation) {
|
||||
if ( annotation != null ) {
|
||||
for ( NamedStoredProcedureQuery queryAnnotation : annotation.value() ) {
|
||||
bindNamedStoredProcedureQuery( mappings, queryAnnotation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void bindNamedStoredProcedureQuery(Mappings mappings, NamedStoredProcedureQuery annotation) {
|
||||
if ( annotation != null ) {
|
||||
QueryBinder.bindNamedStoredProcedureQuery( annotation, mappings );
|
||||
}
|
||||
}
|
||||
|
||||
private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann, Mappings mappings) {
|
||||
IdGenerator idGen = new IdGenerator();
|
||||
if ( mappings.getSchemaName() != null ) {
|
||||
|
|
|
@ -303,7 +303,7 @@ public class Configuration implements Serializable {
|
|||
namedSqlQueries = new HashMap<String,NamedSQLQueryDefinition>();
|
||||
sqlResultSetMappings = new HashMap<String, ResultSetMappingDefinition>();
|
||||
namedEntityGraphMap = new HashMap<String, NamedEntityGraphDefinition>();
|
||||
|
||||
namedProcedureCallMap = new HashMap<String, NamedProcedureCallDefinition>( );
|
||||
typeDefs = new HashMap<String,TypeDef>();
|
||||
filterDefinitions = new HashMap<String, FilterDefinition>();
|
||||
fetchProfiles = new HashMap<String, FetchProfile>();
|
||||
|
|
|
@ -25,25 +25,20 @@ package org.hibernate.cfg.annotations;
|
|||
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.QueryHint;
|
||||
import javax.persistence.StoredProcedureParameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.internal.ParameterStrategy;
|
||||
import org.hibernate.procedure.internal.ProcedureCallMementoImpl;
|
||||
|
@ -65,7 +60,7 @@ public class NamedProcedureCallDefinition {
|
|||
private final Class[] resultClasses;
|
||||
private final String[] resultSetMappings;
|
||||
private final ParameterDefinitions parameterDefinitions;
|
||||
private final Map<String,Object> hints;
|
||||
private final Map<String, Object> hints;
|
||||
|
||||
NamedProcedureCallDefinition(NamedStoredProcedureQuery annotation) {
|
||||
this.registeredName = annotation.name();
|
||||
|
@ -73,7 +68,7 @@ public class NamedProcedureCallDefinition {
|
|||
this.resultClasses = annotation.resultClasses();
|
||||
this.resultSetMappings = annotation.resultSetMappings();
|
||||
this.parameterDefinitions = new ParameterDefinitions( annotation.parameters() );
|
||||
this.hints = extract( annotation.hints() );
|
||||
this.hints = new QueryHintDefinition( annotation.hints() ).getHintsMap();
|
||||
|
||||
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
|
||||
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
|
||||
|
@ -88,17 +83,6 @@ public class NamedProcedureCallDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> extract(QueryHint[] hints) {
|
||||
if ( hints == null || hints.length == 0 ) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final Map<String,Object> hintsMap = new HashMap<String, Object>();
|
||||
for ( QueryHint hint : hints ) {
|
||||
hintsMap.put( hint.name(), hint.value() );
|
||||
}
|
||||
return hintsMap;
|
||||
}
|
||||
|
||||
public String getRegisteredName() {
|
||||
return registeredName;
|
||||
}
|
||||
|
@ -201,7 +185,7 @@ public class NamedProcedureCallDefinition {
|
|||
public List<ParameterMemento> toMementos(SessionFactoryImpl sessionFactory) {
|
||||
final List<ParameterMemento> mementos = new ArrayList<ParameterMemento>();
|
||||
for ( ParameterDefinition definition : parameterDefinitions ) {
|
||||
definition.toMemento( sessionFactory );
|
||||
mementos.add(definition.toMemento( sessionFactory ));
|
||||
}
|
||||
return mementos;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,11 @@
|
|||
*/
|
||||
package org.hibernate.cfg.annotations;
|
||||
import java.util.HashMap;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.NamedNativeQueries;
|
||||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.QueryHint;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.SqlResultSetMappings;
|
||||
|
||||
|
@ -40,7 +38,6 @@ import org.hibernate.AssertionFailure;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.annotations.CacheModeType;
|
||||
import org.hibernate.annotations.FlushModeType;
|
||||
import org.hibernate.annotations.QueryHints;
|
||||
|
@ -54,7 +51,6 @@ import org.hibernate.engine.spi.NamedQueryDefinitionBuilder;
|
|||
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
|
||||
import org.hibernate.engine.spi.NamedSQLQueryDefinitionBuilder;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.LockModeConverter;
|
||||
|
||||
/**
|
||||
* Query binder
|
||||
|
@ -70,19 +66,19 @@ public abstract class QueryBinder {
|
|||
throw new AnnotationException( "A named query must have a name when used in class or package level" );
|
||||
}
|
||||
//EJBQL Query
|
||||
QueryHint[] hints = queryAnn.hints();
|
||||
QueryHintDefinition hints = new QueryHintDefinition( queryAnn.hints() );
|
||||
String queryName = queryAnn.query();
|
||||
NamedQueryDefinition queryDefinition = new NamedQueryDefinitionBuilder( queryAnn.name() )
|
||||
.setLockOptions( determineLockOptions( queryAnn, hints ) )
|
||||
.setLockOptions( hints.determineLockOptions( queryAnn ) )
|
||||
.setQuery( queryName )
|
||||
.setCacheable( getBoolean( queryName, "org.hibernate.cacheable", hints ) )
|
||||
.setCacheRegion( getString( queryName, "org.hibernate.cacheRegion", hints ) )
|
||||
.setTimeout( getTimeout( queryName, hints ) )
|
||||
.setFetchSize( getInteger( queryName, "org.hibernate.fetchSize", hints ) )
|
||||
.setFlushMode( getFlushMode( queryName, hints ) )
|
||||
.setCacheMode( getCacheMode( queryName, hints ) )
|
||||
.setReadOnly( getBoolean( queryName, "org.hibernate.readOnly", hints ) )
|
||||
.setComment( getString( queryName, "org.hibernate.comment", hints ) )
|
||||
.setCacheable( hints.getBoolean( queryName, QueryHints.CACHEABLE ) )
|
||||
.setCacheRegion( hints.getString( queryName, QueryHints.CACHE_REGION ) )
|
||||
.setTimeout( hints.getTimeout( queryName ) )
|
||||
.setFetchSize( hints.getInteger( queryName, QueryHints.FETCH_SIZE ) )
|
||||
.setFlushMode( hints.getFlushMode( queryName ) )
|
||||
.setCacheMode( hints.getCacheMode( queryName ) )
|
||||
.setReadOnly( hints.getBoolean( queryName, QueryHints.READ_ONLY ) )
|
||||
.setComment( hints.getString( queryName, QueryHints.COMMENT ) )
|
||||
.setParameterTypes( null )
|
||||
.createNamedQueryDefinition();
|
||||
|
||||
|
@ -97,17 +93,7 @@ public abstract class QueryBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private static LockOptions determineLockOptions(NamedQuery namedQueryAnnotation, QueryHint[] hints) {
|
||||
LockModeType lockModeType = namedQueryAnnotation.lockMode();
|
||||
Integer lockTimeoutHint = getInteger( namedQueryAnnotation.name(), "javax.persistence.lock.timeout", hints );
|
||||
|
||||
LockOptions lockOptions = new LockOptions( LockModeConverter.convertToLockMode( lockModeType ) );
|
||||
if ( lockTimeoutHint != null ) {
|
||||
lockOptions.setTimeOut( lockTimeoutHint );
|
||||
}
|
||||
|
||||
return lockOptions;
|
||||
}
|
||||
|
||||
public static void bindNativeQuery(NamedNativeQuery queryAnn, Mappings mappings, boolean isDefault) {
|
||||
if ( queryAnn == null ) return;
|
||||
|
@ -116,22 +102,22 @@ public abstract class QueryBinder {
|
|||
throw new AnnotationException( "A named query must have a name when used in class or package level" );
|
||||
}
|
||||
String resultSetMapping = queryAnn.resultSetMapping();
|
||||
QueryHint[] hints = queryAnn.hints();
|
||||
QueryHintDefinition hints = new QueryHintDefinition( queryAnn.hints() );
|
||||
String queryName = queryAnn.query();
|
||||
|
||||
NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder( queryAnn.name() )
|
||||
.setQuery( queryName )
|
||||
.setQuerySpaces( null )
|
||||
.setCacheable( getBoolean( queryName, "org.hibernate.cacheable", hints ) )
|
||||
.setCacheRegion( getString( queryName, "org.hibernate.cacheRegion", hints ) )
|
||||
.setTimeout( getTimeout( queryName, hints ) )
|
||||
.setFetchSize( getInteger( queryName, "org.hibernate.fetchSize", hints ) )
|
||||
.setFlushMode( getFlushMode( queryName, hints ) )
|
||||
.setCacheMode( getCacheMode( queryName, hints ) )
|
||||
.setReadOnly( getBoolean( queryName, "org.hibernate.readOnly", hints ) )
|
||||
.setComment( getString( queryName, "org.hibernate.comment", hints ) )
|
||||
.setCacheable( hints.getBoolean( queryName, QueryHints.CACHEABLE ) )
|
||||
.setCacheRegion( hints.getString( queryName, QueryHints.CACHE_REGION ) )
|
||||
.setTimeout( hints.getTimeout( queryName ) )
|
||||
.setFetchSize( hints.getInteger( queryName, QueryHints.FETCH_SIZE ) )
|
||||
.setFlushMode( hints.getFlushMode( queryName ) )
|
||||
.setCacheMode( hints.getCacheMode( queryName ) )
|
||||
.setReadOnly( hints.getBoolean( queryName, QueryHints.READ_ONLY ) )
|
||||
.setComment( hints.getString( queryName, QueryHints.COMMENT ) )
|
||||
.setParameterTypes( null )
|
||||
.setCallable( getBoolean( queryName, "org.hibernate.callable", hints ) );
|
||||
.setCallable( hints.getBoolean( queryName, QueryHints.CALLABLE ) );
|
||||
|
||||
if ( !BinderHelper.isEmptyAnnotationValue( resultSetMapping ) ) {
|
||||
//sql result set usage
|
||||
|
@ -359,109 +345,5 @@ public abstract class QueryBinder {
|
|||
mappings.addSecondPass( new ResultsetMappingSecondPass( ann, mappings, isDefault ) );
|
||||
}
|
||||
|
||||
private static CacheMode getCacheMode(String query, QueryHint[] hints) {
|
||||
for (QueryHint hint : hints) {
|
||||
if ( "org.hibernate.cacheMode".equals( hint.name() ) ) {
|
||||
if ( hint.value().equalsIgnoreCase( CacheMode.GET.toString() ) ) {
|
||||
return CacheMode.GET;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( CacheMode.IGNORE.toString() ) ) {
|
||||
return CacheMode.IGNORE;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( CacheMode.NORMAL.toString() ) ) {
|
||||
return CacheMode.NORMAL;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( CacheMode.PUT.toString() ) ) {
|
||||
return CacheMode.PUT;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( CacheMode.REFRESH.toString() ) ) {
|
||||
return CacheMode.REFRESH;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Unknown CacheMode in hint: " + query + ":" + hint.name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static FlushMode getFlushMode(String query, QueryHint[] hints) {
|
||||
for (QueryHint hint : hints) {
|
||||
if ( "org.hibernate.flushMode".equals( hint.name() ) ) {
|
||||
if ( hint.value().equalsIgnoreCase( FlushMode.ALWAYS.toString() ) ) {
|
||||
return FlushMode.ALWAYS;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( FlushMode.AUTO.toString() ) ) {
|
||||
return FlushMode.AUTO;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( FlushMode.COMMIT.toString() ) ) {
|
||||
return FlushMode.COMMIT;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( FlushMode.NEVER.toString() ) ) {
|
||||
return FlushMode.MANUAL;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( FlushMode.MANUAL.toString() ) ) {
|
||||
return FlushMode.MANUAL;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Unknown FlushMode in hint: " + query + ":" + hint.name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean getBoolean(String query, String hintName, QueryHint[] hints) {
|
||||
for (QueryHint hint : hints) {
|
||||
if ( hintName.equals( hint.name() ) ) {
|
||||
if ( hint.value().equalsIgnoreCase( "true" ) ) {
|
||||
return true;
|
||||
}
|
||||
else if ( hint.value().equalsIgnoreCase( "false" ) ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Not a boolean in hint: " + query + ":" + hint.name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getString(String query, String hintName, QueryHint[] hints) {
|
||||
for (QueryHint hint : hints) {
|
||||
if ( hintName.equals( hint.name() ) ) {
|
||||
return hint.value();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Integer getInteger(String query, String hintName, QueryHint[] hints) {
|
||||
for (QueryHint hint : hints) {
|
||||
if ( hintName.equals( hint.name() ) ) {
|
||||
try {
|
||||
return Integer.decode( hint.value() );
|
||||
}
|
||||
catch (NumberFormatException nfe) {
|
||||
throw new AnnotationException( "Not an integer in hint: " + query + ":" + hint.name(), nfe );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Integer getTimeout(String queryName, QueryHint[] hints) {
|
||||
Integer timeout = getInteger( queryName, "javax.persistence.query.timeout", hints );
|
||||
|
||||
if ( timeout != null ) {
|
||||
// convert milliseconds to seconds
|
||||
timeout = (int)Math.round(timeout.doubleValue() / 1000.0 );
|
||||
}
|
||||
else {
|
||||
// timeout is already in seconds
|
||||
timeout = getInteger( queryName, "org.hibernate.timeout", hints );
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.cfg.annotations;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.QueryHint;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.QueryHints;
|
||||
import org.hibernate.internal.util.LockModeConverter;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class QueryHintDefinition {
|
||||
private final Map<String, Object> hintsMap;
|
||||
|
||||
public QueryHintDefinition(final QueryHint[] hints) {
|
||||
if ( hints == null || hints.length == 0 ) {
|
||||
hintsMap = Collections.emptyMap();
|
||||
}
|
||||
else {
|
||||
final Map<String, Object> hintsMap = new HashMap<String, Object>();
|
||||
for ( QueryHint hint : hints ) {
|
||||
hintsMap.put( hint.name(), hint.value() );
|
||||
}
|
||||
this.hintsMap = hintsMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CacheMode getCacheMode(String query) {
|
||||
String hitName = QueryHints.CACHE_MODE;
|
||||
String value =(String) hintsMap.get( hitName );
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return CacheMode.interpretExternalSetting( value );
|
||||
}
|
||||
catch ( MappingException e ) {
|
||||
throw new AnnotationException( "Unknown CacheMode in hint: " + query + ":" + hitName, e );
|
||||
}
|
||||
}
|
||||
|
||||
public FlushMode getFlushMode(String query) {
|
||||
String hitName = QueryHints.FLUSH_MODE;
|
||||
String value =(String) hintsMap.get( hitName );
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return FlushMode.interpretExternalSetting( value );
|
||||
}
|
||||
catch ( MappingException e ) {
|
||||
throw new AnnotationException( "Unknown FlushMode in hint: " + query + ":" + hitName, e );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBoolean(String query, String hintName) {
|
||||
String value =(String) hintsMap.get( hintName );
|
||||
if ( value == null ) {
|
||||
return false;
|
||||
}
|
||||
if ( value.equalsIgnoreCase( "true" ) ) {
|
||||
return true;
|
||||
}
|
||||
else if ( value.equalsIgnoreCase( "false" ) ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Not a boolean in hint: " + query + ":" + hintName );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getString(String query, String hintName) {
|
||||
return (String) hintsMap.get( hintName );
|
||||
}
|
||||
|
||||
public Integer getInteger(String query, String hintName) {
|
||||
String value = (String) hintsMap.get( hintName );
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.decode( value );
|
||||
}
|
||||
catch ( NumberFormatException nfe ) {
|
||||
throw new AnnotationException( "Not an integer in hint: " + query + ":" + hintName, nfe );
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getTimeout(String queryName) {
|
||||
Integer timeout = getInteger( queryName, QueryHints.TIMEOUT_JPA );
|
||||
|
||||
if ( timeout != null ) {
|
||||
// convert milliseconds to seconds
|
||||
timeout = (int) Math.round( timeout.doubleValue() / 1000.0 );
|
||||
}
|
||||
else {
|
||||
// timeout is already in seconds
|
||||
timeout = getInteger( queryName, QueryHints.TIMEOUT_HIBERNATE );
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public LockOptions determineLockOptions(NamedQuery namedQueryAnnotation) {
|
||||
LockModeType lockModeType = namedQueryAnnotation.lockMode();
|
||||
Integer lockTimeoutHint = getInteger( namedQueryAnnotation.name(), "javax.persistence.lock.timeout" );
|
||||
|
||||
LockOptions lockOptions = new LockOptions( LockModeConverter.convertToLockMode( lockModeType ) );
|
||||
if ( lockTimeoutHint != null ) {
|
||||
lockOptions.setTimeOut( lockTimeoutHint );
|
||||
}
|
||||
|
||||
return lockOptions;
|
||||
}
|
||||
|
||||
public Map<String, Object> getHintsMap() {
|
||||
return hintsMap;
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ import java.util.Map;
|
|||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
@ -49,6 +50,7 @@ import org.hibernate.internal.util.ReflectHelper;
|
|||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||
private transient MetadataProvider delegate = new JavaMetadataProvider();
|
||||
private transient Map<Object, Object> defaults;
|
||||
|
@ -152,6 +154,16 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
|||
element, xmlDefaults
|
||||
);
|
||||
sqlResultSetMappings.addAll( currentSqlResultSetMappings );
|
||||
|
||||
List<NamedStoredProcedureQuery> namedStoredProcedureQueries = (List<NamedStoredProcedureQuery>)defaults.get( NamedStoredProcedureQuery.class );
|
||||
if(namedStoredProcedureQueries==null){
|
||||
namedStoredProcedureQueries = new ArrayList<NamedStoredProcedureQuery>( );
|
||||
defaults.put( NamedStoredProcedureQuery.class, namedStoredProcedureQueries );
|
||||
}
|
||||
List<NamedStoredProcedureQuery> currentNamedStoredProcedureQueries = JPAOverriddenAnnotationReader.buildNamedStoreProcedureQueries(
|
||||
element, xmlDefaults
|
||||
);
|
||||
namedStoredProcedureQueries.addAll( currentNamedStoredProcedureQueries );
|
||||
}
|
||||
}
|
||||
return defaults;
|
||||
|
|
|
@ -92,10 +92,12 @@ import javax.persistence.NamedNativeQueries;
|
|||
import javax.persistence.NamedNativeQuery;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.OrderColumn;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PostPersist;
|
||||
import javax.persistence.PostRemove;
|
||||
|
@ -111,6 +113,7 @@ import javax.persistence.SecondaryTables;
|
|||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.SqlResultSetMappings;
|
||||
import javax.persistence.StoredProcedureParameter;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.TableGenerator;
|
||||
import javax.persistence.Temporal;
|
||||
|
@ -1743,6 +1746,84 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<NamedStoredProcedureQuery> buildNamedStoreProcedureQueries(Element element, XMLContext.Default defaults) {
|
||||
if ( element == null ) {
|
||||
return new ArrayList<NamedStoredProcedureQuery>();
|
||||
}
|
||||
List namedStoredProcedureElements = element.elements( "named-stored-procedure-query" );
|
||||
List<NamedStoredProcedureQuery> namedStoredProcedureQueries = new ArrayList<NamedStoredProcedureQuery>();
|
||||
for ( Object obj : namedStoredProcedureElements ) {
|
||||
Element subElement = (Element) obj;
|
||||
AnnotationDescriptor ann = new AnnotationDescriptor( NamedStoredProcedureQuery.class );
|
||||
copyStringAttribute( ann, subElement, "name", true );
|
||||
copyStringAttribute( ann, subElement, "procedure-name", true );
|
||||
|
||||
List<Element> elements = subElement.elements( "parameter" );
|
||||
List<StoredProcedureParameter> storedProcedureParameters = new ArrayList<StoredProcedureParameter>();
|
||||
|
||||
for ( Element parameterElement : elements ) {
|
||||
AnnotationDescriptor parameterDescriptor = new AnnotationDescriptor( StoredProcedureParameter.class );
|
||||
copyStringAttribute( parameterDescriptor, parameterElement, "name", false );
|
||||
String modeValue = parameterElement.attributeValue( "mode" );
|
||||
if ( modeValue == null ) {
|
||||
parameterDescriptor.setValue( "mode", ParameterMode.IN );
|
||||
}
|
||||
else {
|
||||
parameterDescriptor.setValue( "mode", ParameterMode.valueOf( modeValue.toUpperCase() ) );
|
||||
}
|
||||
String clazzName = parameterElement.attributeValue( "class" );
|
||||
Class clazz;
|
||||
try {
|
||||
clazz = ReflectHelper.classForName(
|
||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
||||
JPAOverriddenAnnotationReader.class
|
||||
);
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||
}
|
||||
parameterDescriptor.setValue( "type", clazz );
|
||||
storedProcedureParameters.add( (StoredProcedureParameter) AnnotationFactory.create( parameterDescriptor ) );
|
||||
}
|
||||
|
||||
ann.setValue(
|
||||
"parameters",
|
||||
storedProcedureParameters.toArray( new StoredProcedureParameter[storedProcedureParameters.size()] )
|
||||
);
|
||||
|
||||
elements = subElement.elements( "result-class" );
|
||||
List<Class> returnClasses = new ArrayList<Class>();
|
||||
for ( Element classElement : elements ) {
|
||||
String clazzName = classElement.getTextTrim();
|
||||
Class clazz;
|
||||
try {
|
||||
clazz = ReflectHelper.classForName(
|
||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
||||
JPAOverriddenAnnotationReader.class
|
||||
);
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||
}
|
||||
returnClasses.add( clazz );
|
||||
}
|
||||
ann.setValue( "resultClasses", returnClasses.toArray( new Class[returnClasses.size()] ) );
|
||||
|
||||
|
||||
elements = subElement.elements( "result-set-mapping" );
|
||||
List<String> resultSetMappings = new ArrayList<String>();
|
||||
for ( Element resultSetMappingElement : elements ) {
|
||||
resultSetMappings.add( resultSetMappingElement.getTextTrim() );
|
||||
}
|
||||
ann.setValue( "resultSetMappings", resultSetMappings.toArray( new String[resultSetMappings.size()] ) );
|
||||
elements = subElement.elements( "hint" );
|
||||
buildQueryHints( elements, ann );
|
||||
namedStoredProcedureQueries.add( (NamedStoredProcedureQuery) AnnotationFactory.create( ann ) );
|
||||
}
|
||||
return namedStoredProcedureElements;
|
||||
|
||||
}
|
||||
|
||||
public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) {
|
||||
if ( element == null ) {
|
||||
return new ArrayList<SqlResultSetMapping>();
|
||||
|
@ -1910,6 +1991,25 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
}
|
||||
|
||||
private static void buildQueryHints(List<Element> elements, AnnotationDescriptor ann){
|
||||
List<QueryHint> queryHints = new ArrayList<QueryHint>( elements.size() );
|
||||
for ( Element hint : elements ) {
|
||||
AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
|
||||
String value = hint.attributeValue( "name" );
|
||||
if ( value == null ) {
|
||||
throw new AnnotationException( "<hint> without name. " + SCHEMA_VALIDATION );
|
||||
}
|
||||
hintDescriptor.setValue( "name", value );
|
||||
value = hint.attributeValue( "value" );
|
||||
if ( value == null ) {
|
||||
throw new AnnotationException( "<hint> without value. " + SCHEMA_VALIDATION );
|
||||
}
|
||||
hintDescriptor.setValue( "value", value );
|
||||
queryHints.add( (QueryHint) AnnotationFactory.create( hintDescriptor ) );
|
||||
}
|
||||
ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
|
||||
}
|
||||
|
||||
public static List buildNamedQueries(Element element, boolean isNative, XMLContext.Default defaults) {
|
||||
if ( element == null ) {
|
||||
return new ArrayList();
|
||||
|
@ -1931,22 +2031,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
copyStringElement( queryElt, ann, "query" );
|
||||
List<Element> elements = subelement.elements( "hint" );
|
||||
List<QueryHint> queryHints = new ArrayList<QueryHint>( elements.size() );
|
||||
for ( Element hint : elements ) {
|
||||
AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
|
||||
String value = hint.attributeValue( "name" );
|
||||
if ( value == null ) {
|
||||
throw new AnnotationException( "<hint> without name. " + SCHEMA_VALIDATION );
|
||||
}
|
||||
hintDescriptor.setValue( "name", value );
|
||||
value = hint.attributeValue( "value" );
|
||||
if ( value == null ) {
|
||||
throw new AnnotationException( "<hint> without value. " + SCHEMA_VALIDATION );
|
||||
}
|
||||
hintDescriptor.setValue( "value", value );
|
||||
queryHints.add( (QueryHint) AnnotationFactory.create( hintDescriptor ) );
|
||||
}
|
||||
ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
|
||||
buildQueryHints( elements, ann );
|
||||
String clazzName = subelement.attributeValue( "result-class" );
|
||||
if ( StringHelper.isNotEmpty( clazzName ) ) {
|
||||
Class clazz;
|
||||
|
|
|
@ -56,7 +56,7 @@ public class NamedQueryRepository {
|
|||
Iterable<NamedQueryDefinition> namedQueryDefinitions,
|
||||
Iterable<NamedSQLQueryDefinition> namedSqlQueryDefinitions,
|
||||
Iterable<ResultSetMappingDefinition> namedSqlResultSetMappings,
|
||||
List<ProcedureCallMemento> namedProcedureCalls) {
|
||||
Map<String, ProcedureCallMemento> namedProcedureCalls) {
|
||||
final HashMap<String, NamedQueryDefinition> namedQueryDefinitionMap = new HashMap<String, NamedQueryDefinition>();
|
||||
for ( NamedQueryDefinition namedQueryDefinition : namedQueryDefinitions ) {
|
||||
namedQueryDefinitionMap.put( namedQueryDefinition.getName(), namedQueryDefinition );
|
||||
|
@ -75,6 +75,7 @@ public class NamedQueryRepository {
|
|||
namedSqlResultSetMappingMap.put( resultSetMappingDefinition.getName(), resultSetMappingDefinition );
|
||||
}
|
||||
this.namedSqlResultSetMappingMap = Collections.unmodifiableMap( namedSqlResultSetMappingMap );
|
||||
this.procedureCallMementoMap = Collections.unmodifiableMap( namedProcedureCalls );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -580,13 +580,13 @@ public final class SessionFactoryImpl
|
|||
this.observer.sessionFactoryCreated( this );
|
||||
}
|
||||
|
||||
private List<ProcedureCallMemento> toProcedureCallMementos(
|
||||
private Map<String, ProcedureCallMemento> toProcedureCallMementos(
|
||||
Map<String, NamedProcedureCallDefinition> definitions,
|
||||
Map<String, ResultSetMappingDefinition> resultSetMappingMap) {
|
||||
final List<ProcedureCallMemento> rtn = new ArrayList<ProcedureCallMemento>();
|
||||
final Map<String, ProcedureCallMemento> rtn = new HashMap<String, ProcedureCallMemento>();
|
||||
if ( definitions != null ) {
|
||||
for ( NamedProcedureCallDefinition definition : definitions.values() ) {
|
||||
rtn.add( definition.toMemento( this, resultSetMappingMap ) );
|
||||
for (String name : definitions.keySet()){
|
||||
rtn.put( name, definitions.get( name ).toMemento( this, resultSetMappingMap ));
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
|
@ -871,7 +871,7 @@ public final class SessionFactoryImpl
|
|||
metadata.getNamedQueryDefinitions(),
|
||||
metadata.getNamedNativeQueryDefinitions(),
|
||||
metadata.getResultSetMappingDefinitions(),
|
||||
null
|
||||
new HashMap<String, ProcedureCallMemento>( )
|
||||
);
|
||||
|
||||
imports = new HashMap<String,String>();
|
||||
|
|
|
@ -49,7 +49,7 @@ public class ProcedureCallMementoImpl implements ProcedureCallMemento {
|
|||
|
||||
private final Set<String> synchronizedQuerySpaces;
|
||||
|
||||
private final Map<String,Object> hintsMap;
|
||||
private final Map<String, Object> hintsMap;
|
||||
|
||||
/**
|
||||
* Constructs a ProcedureCallImpl
|
||||
|
@ -67,7 +67,7 @@ public class ProcedureCallMementoImpl implements ProcedureCallMemento {
|
|||
ParameterStrategy parameterStrategy,
|
||||
List<ParameterMemento> parameterDeclarations,
|
||||
Set<String> synchronizedQuerySpaces,
|
||||
Map<String,Object> hintsMap) {
|
||||
Map<String, Object> hintsMap) {
|
||||
this.procedureName = procedureName;
|
||||
this.queryReturns = queryReturns;
|
||||
this.parameterStrategy = parameterStrategy;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.hibernate.jpa;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import static org.hibernate.annotations.QueryHints.*;
|
||||
|
||||
/**
|
||||
* Defines the supported JPA query hints
|
||||
|
@ -37,52 +38,52 @@ public class QueryHints {
|
|||
* @deprecated use {@link #SPEC_HINT_TIMEOUT} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String HINT_TIMEOUT = "org.hibernate.timeout";
|
||||
public static final String HINT_TIMEOUT = TIMEOUT_HIBERNATE;
|
||||
|
||||
/**
|
||||
* The hint key for specifying a query timeout per JPA, which defines the timeout in milliseconds
|
||||
*/
|
||||
public static final String SPEC_HINT_TIMEOUT = "javax.persistence.query.timeout";
|
||||
public static final String SPEC_HINT_TIMEOUT = TIMEOUT_JPA;
|
||||
|
||||
/**
|
||||
* The hint key for specifying a comment which is to be embedded into the SQL sent to the database.
|
||||
*/
|
||||
public static final String HINT_COMMENT = "org.hibernate.comment";
|
||||
public static final String HINT_COMMENT = COMMENT;
|
||||
|
||||
/**
|
||||
* The hint key for specifying a JDBC fetch size, used when executing the resulting SQL.
|
||||
*/
|
||||
public static final String HINT_FETCH_SIZE = "org.hibernate.fetchSize";
|
||||
public static final String HINT_FETCH_SIZE = FETCH_SIZE;
|
||||
|
||||
/**
|
||||
* The hint key for specifying whether the query results should be cached for the next (cached) execution of the
|
||||
* "same query".
|
||||
*/
|
||||
public static final String HINT_CACHEABLE = "org.hibernate.cacheable";
|
||||
public static final String HINT_CACHEABLE = CACHEABLE;
|
||||
|
||||
/**
|
||||
* The hint key for specifying the name of the cache region (within Hibernate's query result cache region)
|
||||
* to use for storing the query results.
|
||||
*/
|
||||
public static final String HINT_CACHE_REGION = "org.hibernate.cacheRegion";
|
||||
public static final String HINT_CACHE_REGION = CACHE_REGION;
|
||||
|
||||
/**
|
||||
* The hint key for specifying that objects loaded into the persistence context as a result of this query execution
|
||||
* should be associated with the persistence context as read-only.
|
||||
*/
|
||||
public static final String HINT_READONLY = "org.hibernate.readOnly";
|
||||
public static final String HINT_READONLY = READ_ONLY;
|
||||
|
||||
/**
|
||||
* The hint key for specifying the cache mode ({@link org.hibernate.CacheMode}) to be in effect for the
|
||||
* execution of the hinted query.
|
||||
*/
|
||||
public static final String HINT_CACHE_MODE = "org.hibernate.cacheMode";
|
||||
public static final String HINT_CACHE_MODE = CACHE_MODE;
|
||||
|
||||
/**
|
||||
* The hint key for specifying the flush mode ({@link org.hibernate.FlushMode}) to be in effect for the
|
||||
* execution of the hinted query.
|
||||
*/
|
||||
public static final String HINT_FLUSH_MODE = "org.hibernate.flushMode";
|
||||
public static final String HINT_FLUSH_MODE = FLUSH_MODE;
|
||||
|
||||
private static final Set<String> HINTS = buildHintsSet();
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package org.hibernate.jpa.test.procedure;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
import org.hibernate.procedure.internal.ParameterStrategy;
|
||||
import org.hibernate.procedure.internal.ProcedureCallMementoImpl;
|
||||
import org.hibernate.type.IntegerType;
|
||||
import org.hibernate.type.LongType;
|
||||
import org.hibernate.type.StringType;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public abstract class AbstractStoredProcedureTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Test
|
||||
public void testNamedStoredProcedureBinding() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
SessionFactoryImplementor sf = em.getEntityManagerFactory().unwrap( SessionFactoryImplementor.class );
|
||||
final ProcedureCallMementoImpl m1 = (ProcedureCallMementoImpl) sf.getNamedQueryRepository()
|
||||
.getNamedProcedureCallMemento( "s1" );
|
||||
assertNotNull( m1 );
|
||||
assertEquals( "p1", m1.getProcedureName() );
|
||||
assertEquals( ParameterStrategy.NAMED, m1.getParameterStrategy() );
|
||||
List<ProcedureCallMementoImpl.ParameterMemento> list = m1.getParameterDeclarations();
|
||||
assertEquals( 2, list.size() );
|
||||
ProcedureCallMementoImpl.ParameterMemento memento = list.get( 0 );
|
||||
assertEquals( "p11", memento.getName() );
|
||||
assertEquals( javax.persistence.ParameterMode.IN, memento.getMode() );
|
||||
assertEquals( IntegerType.INSTANCE, memento.getHibernateType() );
|
||||
assertEquals( Integer.class, memento.getType() );
|
||||
|
||||
memento = list.get( 1 );
|
||||
assertEquals( "p12", memento.getName() );
|
||||
assertEquals( javax.persistence.ParameterMode.IN, memento.getMode() );
|
||||
assertEquals( IntegerType.INSTANCE, memento.getHibernateType() );
|
||||
assertEquals( Integer.class, memento.getType() );
|
||||
|
||||
|
||||
|
||||
final ProcedureCallMementoImpl m2 = (ProcedureCallMementoImpl) sf.getNamedQueryRepository()
|
||||
.getNamedProcedureCallMemento( "s2" );
|
||||
assertNotNull( m2 );
|
||||
assertEquals( "p2", m2.getProcedureName() );
|
||||
assertEquals( ParameterStrategy.POSITIONAL, m2.getParameterStrategy() );
|
||||
list = m2.getParameterDeclarations();
|
||||
|
||||
memento = list.get( 0 );
|
||||
assertEquals( Integer.valueOf( 0 ), memento.getPosition() );
|
||||
assertEquals( javax.persistence.ParameterMode.INOUT, memento.getMode() );
|
||||
assertEquals( StringType.INSTANCE, memento.getHibernateType() );
|
||||
assertEquals( String.class, memento.getType() );
|
||||
|
||||
memento = list.get( 1 );
|
||||
assertEquals( Integer.valueOf( 1 ), memento.getPosition() );
|
||||
assertEquals( javax.persistence.ParameterMode.INOUT, memento.getMode() );
|
||||
assertEquals( LongType.INSTANCE, memento.getHibernateType() );
|
||||
assertEquals( Long.class, memento.getType() );
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.jpa.test.procedure;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class AnnotationTest extends AbstractStoredProcedureTest {
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { User.class };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.jpa.test.procedure;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
public class OrmTest extends AbstractStoredProcedureTest{
|
||||
@Override
|
||||
public String[] getEjb3DD() {
|
||||
return new String[]{"org/hibernate/jpa/test/procedure/orm.xml"};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package org.hibernate.jpa.test.procedure;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityResult;
|
||||
import javax.persistence.FieldResult;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.NamedStoredProcedureQueries;
|
||||
import javax.persistence.NamedStoredProcedureQuery;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
import javax.persistence.StoredProcedureParameter;
|
||||
|
||||
/**
|
||||
* @author Strong Liu <stliu@hibernate.org>
|
||||
*/
|
||||
@Entity
|
||||
@NamedStoredProcedureQueries(
|
||||
{
|
||||
@NamedStoredProcedureQuery(
|
||||
name = "s1",
|
||||
procedureName = "p1",
|
||||
parameters = {
|
||||
@StoredProcedureParameter(name = "p11",
|
||||
mode = ParameterMode.IN,
|
||||
type = Integer.class),
|
||||
@StoredProcedureParameter(name = "p12",
|
||||
mode = ParameterMode.IN,
|
||||
type = Integer.class
|
||||
)
|
||||
},
|
||||
resultClasses = { User.class }
|
||||
),
|
||||
@NamedStoredProcedureQuery(
|
||||
name = "s2",
|
||||
procedureName = "p2",
|
||||
parameters = {
|
||||
@StoredProcedureParameter(
|
||||
mode = ParameterMode.INOUT,
|
||||
type = String.class),
|
||||
@StoredProcedureParameter(
|
||||
mode = ParameterMode.INOUT,
|
||||
type = Long.class)
|
||||
},
|
||||
resultSetMappings = { "srms" }
|
||||
|
||||
)
|
||||
}
|
||||
)
|
||||
@SqlResultSetMapping(name = "srms",
|
||||
entities = {
|
||||
@EntityResult(entityClass = User.class, fields = {
|
||||
@FieldResult(name = "id", column = "order_id"),
|
||||
@FieldResult(name = "name", column = "order_item")
|
||||
})
|
||||
}
|
||||
)
|
||||
public class User {
|
||||
@Id
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
version="2.1"
|
||||
>
|
||||
<package>org.hibernate.jpa.test.procedure</package>
|
||||
<entity class="User" metadata-complete="true">
|
||||
<named-stored-procedure-query name="s1" procedure-name="p1">
|
||||
<parameter class="java.lang.Integer" mode="IN" name="p11"/>
|
||||
<parameter class="java.lang.Integer" mode="IN" name="p12"/>
|
||||
</named-stored-procedure-query>
|
||||
<named-stored-procedure-query name="s2" procedure-name="p2">
|
||||
<parameter class="java.lang.String" mode="INOUT"/>
|
||||
<parameter class="java.lang.Long" mode="INOUT"/>
|
||||
</named-stored-procedure-query>
|
||||
<sql-result-set-mapping name="srms">
|
||||
<entity-result entity-class="User">
|
||||
<field-result name="id" column="order_id"/>
|
||||
<field-result name="name" column="order_item"/>
|
||||
</entity-result>
|
||||
</sql-result-set-mapping>
|
||||
<attributes>
|
||||
<id name="id">
|
||||
<column name="fld_id"/>
|
||||
</id>
|
||||
<basic name="name"/>
|
||||
</attributes>
|
||||
</entity>
|
||||
</entity-mappings>
|
Loading…
Reference in New Issue