Source code: org/hibernate/test/connections/AggressiveReleaseTest.java
1 // $Id: AggressiveReleaseTest.java 9714 2006-03-29 14:35:31Z steve.ebersole@jboss.com $
2 package org.hibernate.test.connections;
3
4 import org.hibernate.Session;
5 import org.hibernate.ConnectionReleaseMode;
6 import org.hibernate.ScrollableResults;
7 import org.hibernate.Hibernate;
8 import org.hibernate.transaction.CMTTransactionFactory;
9 import org.hibernate.impl.SessionImpl;
10 import org.hibernate.util.SerializationHelper;
11 import org.hibernate.test.tm.DummyConnectionProvider;
12 import org.hibernate.test.tm.DummyTransactionManagerLookup;
13 import org.hibernate.test.tm.DummyTransactionManager;
14 import org.hibernate.cfg.Configuration;
15 import org.hibernate.cfg.Environment;
16
17 import junit.framework.Test;
18 import junit.framework.TestSuite;
19
20 import java.sql.Connection;
21 import java.util.List;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24
25 /**
26 * Implementation of AggressiveReleaseTest.
27 *
28 * @author Steve Ebersole
29 */
30 public class AggressiveReleaseTest extends ConnectionManagementTestCase {
31
32 public AggressiveReleaseTest(String name) {
33 super( name );
34 }
35
36 public static Test suite() {
37 return new TestSuite( AggressiveReleaseTest.class );
38 }
39
40 protected void configure(Configuration cfg) {
41 super.configure( cfg );
42 cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
43 cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
44 cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
45 cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() );
46 cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
47 cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
48 }
49
50 protected Session getSessionUnderTest() throws Throwable {
51 return openSession();
52 }
53
54 protected void reconnect(Session session) {
55 session.reconnect();
56 }
57
58 protected void prepare() throws Throwable {
59 DummyTransactionManager.INSTANCE.begin();
60 }
61
62 protected void done() throws Throwable {
63 DummyTransactionManager.INSTANCE.commit();
64 }
65
66 // Some additional tests specifically for the aggressive-release functionality...
67
68 public void testSerializationOnAfterStatementAggressiveRelease() throws Throwable {
69 prepare();
70 Session s = getSessionUnderTest();
71 Silly silly = new Silly( "silly" );
72 s.save( silly );
73
74 // this should cause the CM to obtain a connection, and then release it
75 s.flush();
76
77 // We should be able to serialize the session at this point...
78 SerializationHelper.serialize( s );
79
80 s.delete( silly );
81 s.flush();
82
83 release( s );
84 done();
85 }
86
87 public void testSerializationFailsOnAfterStatementAggressiveReleaseWithOpenResources() throws Throwable {
88 prepare();
89 Session s = getSessionUnderTest();
90
91 Silly silly = new Silly( "silly" );
92 s.save( silly );
93
94 // this should cause the CM to obtain a connection, and then release it
95 s.flush();
96
97 // both scroll() and iterate() cause the batcher to hold on
98 // to resources, which should make aggresive-release not release
99 // the connection (and thus cause serialization to fail)
100 ScrollableResults sr = s.createQuery( "from Silly" ).scroll();
101
102 try {
103 SerializationHelper.serialize( s );
104 fail( "Serialization allowed on connected session; or aggressive release released connection with open resources" );
105 }
106 catch( IllegalStateException e ) {
107 // expected behavior
108 }
109
110 // Closing the ScrollableResults does currently force the batcher to
111 // aggressively release the connection
112 sr.close();
113 SerializationHelper.serialize( s );
114
115 s.delete( silly );
116 s.flush();
117
118 release( s );
119 done();
120 }
121
122 public void testQueryIteration() throws Throwable {
123 prepare();
124 Session s = getSessionUnderTest();
125 Silly silly = new Silly( "silly" );
126 s.save( silly );
127 s.flush();
128
129 Iterator itr = s.createQuery( "from Silly" ).iterate();
130 assertTrue( itr.hasNext() );
131 Silly silly2 = ( Silly ) itr.next();
132 assertEquals( silly, silly2 );
133 Hibernate.close( itr );
134
135 itr = s.createQuery( "from Silly" ).iterate();
136 Iterator itr2 = s.createQuery( "from Silly where name = 'silly'" ).iterate();
137
138 assertTrue( itr.hasNext() );
139 assertEquals( silly, itr.next() );
140 assertTrue( itr2.hasNext() );
141 assertEquals( silly, itr2.next() );
142
143 Hibernate.close( itr );
144 Hibernate.close( itr2 );
145
146 s.delete( silly );
147 s.flush();
148
149 release( s );
150 done();
151 }
152
153 public void testQueryScrolling() throws Throwable {
154 prepare();
155 Session s = getSessionUnderTest();
156 Silly silly = new Silly( "silly" );
157 s.save( silly );
158 s.flush();
159
160 ScrollableResults sr = s.createQuery( "from Silly" ).scroll();
161 assertTrue( sr.next() );
162 Silly silly2 = ( Silly ) sr.get( 0 );
163 assertEquals( silly, silly2 );
164 sr.close();
165
166 sr = s.createQuery( "from Silly" ).scroll();
167 ScrollableResults sr2 = s.createQuery( "from Silly where name = 'silly'" ).scroll();
168
169 assertTrue( sr.next() );
170 assertEquals( silly, sr.get( 0 ) );
171 assertTrue( sr2.next() );
172 assertEquals( silly, sr2.get( 0 ) );
173
174 sr.close();
175 sr2.close();
176
177 s.delete( silly );
178 s.flush();
179
180 release( s );
181 done();
182 }
183
184 public void testSuppliedConnection() throws Throwable {
185 prepare();
186
187 Connection originalConnection = DummyTransactionManager.INSTANCE.getCurrent().getConnection();
188 Session session = getSessions().openSession( originalConnection );
189
190 Silly silly = new Silly( "silly" );
191 session.save( silly );
192
193 // this will cause the connection manager to cycle through the aggressive release logic;
194 // it should not release the connection since we explicitly suplied it ourselves.
195 session.flush();
196
197 assertTrue( "Different connections", originalConnection == session.connection() );
198
199 session.delete( silly );
200 session.flush();
201
202 release( session );
203 done();
204 }
205
206 public void testBorrowedConnections() throws Throwable {
207 prepare();
208 Session s = getSessionUnderTest();
209
210 Connection conn = s.connection();
211 assertTrue( ( ( SessionImpl ) s ).getJDBCContext().getConnectionManager().hasBorrowedConnection() );
212 conn.close();
213 assertFalse( ( ( SessionImpl ) s ).getJDBCContext().getConnectionManager().hasBorrowedConnection() );
214
215 release( s );
216 done();
217 }
218
219 public void testConnectionMaintanenceDuringFlush() throws Throwable {
220 prepare();
221 Session s = getSessionUnderTest();
222 s.beginTransaction();
223
224 List entities = new ArrayList();
225 for ( int i = 0; i < 10; i++ ) {
226 Other other = new Other( "other-" + i );
227 Silly silly = new Silly( "silly-" + i, other );
228 entities.add( silly );
229 s.save( silly );
230 }
231 s.flush();
232
233 Iterator itr = entities.iterator();
234 while ( itr.hasNext() ) {
235 Silly silly = ( Silly ) itr.next();
236 silly.setName( "new-" + silly.getName() );
237 silly.getOther().setName( "new-" + silly.getOther().getName() );
238 }
239 long initialCount = getSessions().getStatistics().getConnectCount();
240 s.flush();
241 assertEquals( "connection not maintained through flush", initialCount + 1, getSessions().getStatistics().getConnectCount() );
242
243 s.createQuery( "delete from Silly" ).executeUpdate();
244 s.createQuery( "delete from Other" ).executeUpdate();
245 s.getTransaction().commit();
246 release( s );
247 done();
248 }
249 }