/* * 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.test.sql.storedproc; import java.math.BigDecimal; import java.util.Date; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ParameterMode; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.dialect.PostgreSQL82Dialect; import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.ProcedureOutputs; import org.hibernate.result.ResultSetOutput; import org.hibernate.testing.FailureExpected; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; /** * @author Steve Ebersole */ @RequiresDialect( value = PostgreSQL81Dialect.class, strictMatching = false ) @FailureExpected( jiraKey = "HHH-8445", message = "Waiting on EG clarification" ) public class PostgresRefCursorSupportTest extends BaseUnitTestCase { public static class ProcedureDefinitions implements AuxiliaryDatabaseObject, AuxiliaryDatabaseObject.Expandable { /** * Singleton access */ public static final ProcedureDefinitions INSTANCE = new ProcedureDefinitions(); @Override public void addDialectScope(String dialectName) { throw new IllegalStateException( "Not expecting addition of dialects to scope" ); } @Override public boolean appliesToDialect(Dialect dialect) { return PostgreSQL81Dialect.class.isInstance( dialect ) || PostgreSQL82Dialect.class.isInstance( dialect ); } @Override public boolean beforeTablesOnCreation() { return true; } @Override public String getExportIdentifier() { return "function:all_items"; } @Override public String[] sqlCreateStrings(Dialect dialect) { return new String[] { "create function all_items() return refcursor as \n" + " 'declare someCursor refcursor;\n" + " begin\n" + " open someCursor for select * from ITEM;\n" + " return someCursor;\n" + " end;' language plpgsql;" }; } @Override public String[] sqlDropStrings(Dialect dialect) { return new String[] { "drop function all_items()" }; } } @Entity @Table( name = "PROC_ITEM" ) public static class Item { @Id private Integer id; private String stockCode; private String name; private BigDecimal unitCost; @Temporal( TemporalType.TIMESTAMP ) private Date availabilityStartDate; @Temporal( TemporalType.TIMESTAMP ) private Date availabilityEndDate; } private SessionFactory sf; @Before public void beforeTest() { Configuration cfg = new Configuration() .addAnnotatedClass( Item.class ) .setProperty( AvailableSettings.HBM2DDL_AUTO, "create-drop" ); cfg.addAuxiliaryDatabaseObject( ProcedureDefinitions.INSTANCE ); sf = cfg.buildSessionFactory(); } @After public void afterTest() { if ( sf != null ) { sf.close(); } } @Test public void testExplicitClassReturn() { Session session = sf.openSession(); session.beginTransaction(); ProcedureCall call = session.createStoredProcedureCall( "all_items", Item.class ); call.registerParameter( 1, void.class, ParameterMode.REF_CURSOR ); ProcedureOutputs outputs = call.getOutputs(); ResultSetOutput results = assertTyping( ResultSetOutput.class, outputs.getCurrent() ); session.getTransaction().commit(); session.close(); } }