[hibernate-commits] Hibernate SVN: r19219 - in core/trunk/entitymanager/src: test/java/org/hibernate/ejb/test and 1 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Tue Apr 13 09:35:39 EDT 2010
Author: epbernard
Date: 2010-04-13 09:35:38 -0400 (Tue, 13 Apr 2010)
New Revision: 19219
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/Item.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/query/QueryTest.java
Log:
HHH-5106 add support for SQL Named Typed-Query
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2010-04-13 08:51:33 UTC (rev 19218)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2010-04-13 13:35:38 UTC (rev 19219)
@@ -93,12 +93,17 @@
import org.hibernate.ejb.util.CacheModeHelper;
import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.ejb.util.LockModeTypeHelper;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.transaction.TransactionFactory;
import org.hibernate.transform.BasicTransformerAdapter;
import org.hibernate.util.JTAHelper;
+import org.hibernate.util.ReflectHelper;
/**
* @author <a href="mailto:gavin at hibernate.org">Gavin King</a>
@@ -449,18 +454,60 @@
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
try {
+ /*
+ * Get the named query.
+ * If the named query is a SQL query, get the expected returned type from the query definition
+ * or its associated result set mapping
+ * If the named query is a HQL query, use getReturnType()
+ */
org.hibernate.Query namedQuery = getSession().getNamedQuery( name );
+ //TODO clean this up to avoid downcasting
+ final SessionFactoryImplementor factoryImplementor = ( SessionFactoryImplementor ) entityManagerFactory.getSessionFactory();
+ final NamedSQLQueryDefinition queryDefinition = factoryImplementor.getNamedSQLQuery( name );
try {
- if ( namedQuery.getReturnTypes().length != 1 ) {
- throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" );
+ if ( queryDefinition != null ) {
+ Class<?> actualReturnedClass;
+
+ final NativeSQLQueryReturn[] queryReturns;
+ if ( queryDefinition.getQueryReturns() != null ) {
+ queryReturns = queryDefinition.getQueryReturns();
+ }
+ else if ( queryDefinition.getResultSetRef() != null ) {
+ final ResultSetMappingDefinition rsMapping = factoryImplementor.getResultSetMapping(
+ queryDefinition.getResultSetRef()
+ );
+ queryReturns = rsMapping.getQueryReturns();
+ }
+ else {
+ throw new AssertionFailure( "Unsupported named query model. Please report the bug in Hibernate EntityManager");
+ }
+ if ( queryReturns.length > 1 ) {
+ throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" );
+ }
+ final NativeSQLQueryReturn nativeSQLQueryReturn = queryReturns[0];
+ if ( nativeSQLQueryReturn instanceof NativeSQLQueryRootReturn ) {
+ final String entityClassName = ( ( NativeSQLQueryRootReturn ) nativeSQLQueryReturn ).getReturnEntityName();
+ try {
+ actualReturnedClass = ReflectHelper.classForName( entityClassName, AbstractEntityManagerImpl.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new AssertionFailure( "Unable to instantiate class declared on named native query: " + name + " " + entityClassName );
+ }
+ if ( !resultClass.isAssignableFrom( actualReturnedClass ) ) {
+ throw buildIncompatibleException( resultClass, actualReturnedClass );
+ }
+ }
+ else {
+ //TODO support other NativeSQLQueryReturn type. For now let it go.
+ }
}
- if ( !resultClass.isAssignableFrom( namedQuery.getReturnTypes()[0].getReturnedClass() ) ) {
- throw new IllegalArgumentException(
- "Type specified for TypedQuery [" +
- resultClass.getName() +
- "] is incompatible with query return type [" +
- namedQuery.getReturnTypes()[0].getReturnedClass() + "]"
- );
+ else {
+ if ( namedQuery.getReturnTypes().length != 1 ) {
+ throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" );
+ }
+ if ( !resultClass.isAssignableFrom( namedQuery.getReturnTypes()[0].getReturnedClass() ) ) {
+ throw buildIncompatibleException( resultClass, namedQuery.getReturnTypes()[0].getReturnedClass() );
+ }
}
return new QueryImpl<T>( namedQuery, this );
}
@@ -473,6 +520,15 @@
}
}
+ private IllegalArgumentException buildIncompatibleException(Class<?> resultClass, Class<?> actualResultClass) {
+ return new IllegalArgumentException(
+ "Type specified for TypedQuery [" +
+ resultClass.getName() +
+ "] is incompatible with query return type [" +
+ actualResultClass + "]"
+ );
+ }
+
public Query createNativeQuery(String sqlString) {
try {
SQLQuery q = getSession().createSQLQuery( sqlString );
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/Item.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/Item.java 2010-04-13 08:51:33 UTC (rev 19218)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/Item.java 2010-04-13 13:35:38 UTC (rev 19219)
@@ -9,6 +9,9 @@
import javax.persistence.EntityResult;
import javax.persistence.FieldResult;
import javax.persistence.Id;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SqlResultSetMapping;
@@ -16,12 +19,24 @@
* @author Gavin King
*/
@Entity(name = "Item")
- at SqlResultSetMapping(name = "getItem", entities =
- at EntityResult(entityClass = org.hibernate.ejb.test.Item.class, fields = {
- at FieldResult(name = "name", column = "itemname"),
- at FieldResult(name = "descr", column = "itemdescription")
- })
+ @SqlResultSetMapping(name = "getItem", entities =
+ @EntityResult(entityClass = org.hibernate.ejb.test.Item.class, fields = {
+ @FieldResult(name = "name", column = "itemname"),
+ @FieldResult(name = "descr", column = "itemdescription")
+ })
)
+ at NamedNativeQueries({
+ @NamedNativeQuery(
+ name = "nativeItem1",
+ query = "select name as itemname, descr as itemdescription from Item",
+ resultSetMapping = "getItem"
+ ),
+ @NamedNativeQuery(
+ name = "nativeItem2",
+ query = "select * from Item",
+ resultClass = Item.class
+ )
+})
//@Cache(region="Item", usage=NONSTRICT_READ_WRITE)
public class Item implements Serializable {
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/query/QueryTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/query/QueryTest.java 2010-04-13 08:51:33 UTC (rev 19218)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/query/QueryTest.java 2010-04-13 13:35:38 UTC (rev 19219)
@@ -435,6 +435,26 @@
}
+ public void testTypedNamedNativeQuery() {
+ Item item = new Item( "Mouse", "Micro$oft mouse" );
+
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ em.persist( item );
+ assertTrue( em.contains( item ) );
+ em.getTransaction().commit();
+
+ em.getTransaction().begin();
+ item = em.createNamedQuery( "nativeItem1", Item.class ).getSingleResult();
+ item = em.createNamedQuery( "nativeItem2", Item.class ).getSingleResult();
+ assertNotNull( item );
+ assertEquals( "Micro$oft mouse", item.getDescr() );
+ em.remove( item );
+ em.getTransaction().commit();
+
+ em.close();
+ }
+
public Class[] getAnnotatedClasses() {
return new Class[]{
Item.class,
More information about the hibernate-commits
mailing list