1+ using System ;
2+ using System . Linq ;
3+ using NHibernate . AdoNet ;
4+ using NHibernate . Cfg ;
5+ using NHibernate . Cfg . MappingSchema ;
6+ using NHibernate . Driver ;
7+ using NHibernate . Engine ;
8+ using NHibernate . Linq ;
9+ using NHibernate . Mapping . ByCode ;
10+ using NUnit . Framework ;
11+
12+ namespace NHibernate . Test . NHSpecificTest . NH3912
13+ {
14+ public class ReusableBatcherFixture : TestCaseMappingByCode
15+ {
16+ protected override bool AppliesTo ( ISessionFactoryImplementor factory )
17+ {
18+ var driver = factory . ConnectionProvider . Driver ;
19+ return driver is OracleDataClientDriver ||
20+ driver is OracleLiteDataClientDriver ||
21+ driver is OracleManagedDataClientDriver ;
22+ }
23+
24+ protected override HbmMapping GetMappings ( )
25+ {
26+ var mapper = new ModelMapper ( ) ;
27+ mapper . Class < BatcherLovingEntity > ( rc =>
28+ {
29+ rc . Id ( x => x . Id , m => m . Generator ( Generators . GuidComb ) ) ;
30+ rc . Property ( x => x . Name , m => m . Unique ( true ) ) ;
31+ } ) ;
32+
33+ return mapper . CompileMappingForAllExplicitlyAddedEntities ( ) ;
34+ }
35+
36+ protected override void Configure ( Configuration configuration )
37+ {
38+ base . Configure ( configuration ) ;
39+ configuration . SetProperty ( Cfg . Environment . BatchStrategy ,
40+ typeof ( OracleDataClientBatchingBatcherFactory ) . AssemblyQualifiedName ) ;
41+ }
42+
43+ protected override void OnSetUp ( )
44+ {
45+ using ( var session = OpenSession ( ) )
46+ using ( var transaction = session . BeginTransaction ( ) )
47+ {
48+ var e1 = new BatcherLovingEntity { Name = "Bob" } ;
49+ session . Save ( e1 ) ;
50+
51+ var e2 = new BatcherLovingEntity { Name = "Sally" } ;
52+ session . Save ( e2 ) ;
53+
54+ session . Flush ( ) ;
55+ transaction . Commit ( ) ;
56+ }
57+ }
58+
59+ protected override void OnTearDown ( )
60+ {
61+ using ( var session = OpenSession ( ) )
62+ using ( var transaction = session . BeginTransaction ( ) )
63+ {
64+ session . Delete ( "from System.Object" ) ;
65+
66+ session . Flush ( ) ;
67+ transaction . Commit ( ) ;
68+ }
69+ }
70+
71+ /// <summary> Batch operations with the same IBatcher instance fail on expect rows count after single failed operation. </summary>
72+ [ Test ]
73+ public void Test_Batcher_Is_Reusable_After_Failed_Operation ( )
74+ {
75+ using ( var session = OpenSession ( ) )
76+ {
77+ try
78+ {
79+ using ( session . BeginTransaction ( ) )
80+ {
81+ var valid = new BatcherLovingEntity { Name = "Bill" } ;
82+ session . Save ( valid ) ;
83+
84+ Assert . That ( ( ) => session . Query < BatcherLovingEntity > ( ) . Count ( x => x . Name == "Bob" ) , Is . EqualTo ( 1 ) ) ;
85+ var bob = new BatcherLovingEntity { Name = "Bob" } ;
86+ session . Save ( bob ) ;
87+
88+ // Should fail on unique constraint violation
89+ // Expected behavior
90+ session . Flush ( ) ;
91+ }
92+ }
93+ catch ( Exception )
94+ {
95+ // Opening next transaction in the same session after rollback
96+ // to log the problem, for instance.
97+ // Executing in the same session with the same instance of IBatcher
98+ using ( session . BeginTransaction ( ) )
99+ {
100+ // Inserting any valid entity will fail on expected rows count assert in batcher
101+ var e1 = new BatcherLovingEntity { Name = "Robert (because Bob already exists)" } ;
102+ session . Save ( e1 ) ;
103+ // Batch update returned unexpected row count from update; actual row count: 1; expected: 2
104+ session . Flush ( ) ;
105+ }
106+ }
107+ }
108+ }
109+ }
110+ }
0 commit comments