Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 339905
Collapse All | Expand All

(-)dbws/org.eclipse.persistence.dbws/src/org/eclipse/persistence/internal/xr/StoredFunctionQueryHandler.java (-1 / +1 lines)
Lines 66-72 Link Here
66
                platform = new DatabasePlatform();
66
                platform = new DatabasePlatform();
67
            }
67
            }
68
            // StoredFunction's return value is the first parameter
68
            // StoredFunction's return value is the first parameter
69
            ((DatabaseField)sfCall.getParameters().firstElement()).setSqlType(
69
            ((DatabaseField)sfCall.getParameters().get(0)).setSqlType(
70
                platform.getJDBCType(clz));
70
                platform.getJDBCType(clz));
71
        }
71
        }
72
    }
72
    }
(-)foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/plsql/PLSQLProject.java (+73 lines)
Lines 15-20 Link Here
15
import org.eclipse.persistence.queries.DataModifyQuery;
15
import org.eclipse.persistence.queries.DataModifyQuery;
16
import org.eclipse.persistence.queries.DataReadQuery;
16
import org.eclipse.persistence.queries.DataReadQuery;
17
import org.eclipse.persistence.queries.DatabaseQuery;
17
import org.eclipse.persistence.queries.DatabaseQuery;
18
import org.eclipse.persistence.queries.StoredProcedureCall;
18
import org.eclipse.persistence.sessions.Project;
19
import org.eclipse.persistence.sessions.Project;
19
20
20
/**
21
/**
Lines 105-110 Link Here
105
        return query;
106
        return query;
106
    }
107
    }
107
    
108
    
109
    protected DatabaseQuery buildSimpleInDefaults2Query() {
110
        PLSQLStoredProcedureCall call = new PLSQLStoredProcedureCall();
111
        call.setProcedureName("PLSQL_SIMPLE_IN_DEFAULTS");
112
        call.addNamedArgument("P_VARCHAR", JDBCTypes.VARCHAR_TYPE, 30);
113
        call.addNamedArgument("P_BOOLEAN", OraclePLSQLTypes.PLSQLBoolean);
114
        call.addNamedArgument("P_BINARY_INTEGER", OraclePLSQLTypes.BinaryInteger);
115
        call.addNamedArgument("P_DEC", OraclePLSQLTypes.Dec);
116
        call.addNamedArgument("P_INT", OraclePLSQLTypes.Int);
117
        call.addNamedArgument("P_NATURAL", OraclePLSQLTypes.Natural);
118
        call.addNamedArgument("P_NATURALN", OraclePLSQLTypes.NaturalN);
119
        call.addNamedArgument("P_PLS_INTEGER", OraclePLSQLTypes.PLSQLInteger);
120
        call.addNamedArgument("P_POSITIVE", OraclePLSQLTypes.Positive);
121
        call.addNamedArgument("P_POSITIVEN", OraclePLSQLTypes.PositiveN);
122
        call.addNamedArgument("P_SIGNTYPE", OraclePLSQLTypes.SignType);
123
        call.addNamedArgument("P_NUMBER", JDBCTypes.NUMERIC_TYPE, 10, 2);
124
        
125
        call.addOptionalArgument("P_VARCHAR");
126
        call.addOptionalArgument("P_BOOLEAN");
127
        call.addOptionalArgument("P_BINARY_INTEGER");
128
        call.addOptionalArgument("P_DEC");
129
        call.addOptionalArgument("P_INT");
130
        call.addOptionalArgument("P_NATURAL");
131
        call.addOptionalArgument("P_NATURALN");
132
        call.addOptionalArgument("P_PLS_INTEGER");
133
        call.addOptionalArgument("P_POSITIVE");
134
        call.addOptionalArgument("P_POSITIVEN");
135
        call.addOptionalArgument("P_SIGNTYPE");
136
        call.addOptionalArgument("P_NUMBER");
137
        
138
        DataModifyQuery query = new DataModifyQuery();
139
        query.addArgument("P_VARCHAR", String.class, true);
140
        query.addArgument("P_BOOLEAN", Integer.class, true);
141
        query.addArgument("P_BINARY_INTEGER", Integer.class, true);
142
        query.addArgument("P_DEC", Integer.class, true);
143
        query.addArgument("P_INT", Integer.class, true);
144
        query.addArgument("P_NATURAL", Integer.class, true);
145
        query.addArgument("P_NATURALN", Integer.class, true);
146
        query.addArgument("P_PLS_INTEGER", Integer.class, true);
147
        query.addArgument("P_POSITIVE", Integer.class, true);
148
        query.addArgument("P_POSITIVEN", Integer.class, true);
149
        query.addArgument("P_SIGNTYPE", BigDecimal.class, true);
150
        query.addArgument("P_NUMBER", BigDecimal.class, true);
151
        query.setCall(call);
152
        
153
        return query;
154
    }
155
    
108
    protected DatabaseQuery buildSimpleInFuncQuery() {
156
    protected DatabaseQuery buildSimpleInFuncQuery() {
109
        PLSQLStoredFunctionCall call = new PLSQLStoredFunctionCall(OraclePLSQLTypes.PLSQLBoolean);
157
        PLSQLStoredFunctionCall call = new PLSQLStoredFunctionCall(OraclePLSQLTypes.PLSQLBoolean);
110
        call.setProcedureName("PLSQL_SIMPLE_IN_Func");
158
        call.setProcedureName("PLSQL_SIMPLE_IN_Func");
Lines 444-450 Link Here
444
492
445
        return query;
493
        return query;
446
    }
494
    }
495
    
496
    protected DatabaseQuery buildAddressOutCursorQuery() {
497
        
498
        StoredProcedureCall call = new StoredProcedureCall();
499
        call.setProcedureName("PLSQL_P.PLSQL_ADDRESS_CUR_OUT");
500
        call.useNamedCursorOutputAsResultSet("P_ADDRESS");
501
        DataReadQuery query = new DataReadQuery();
502
        query.setCall(call);
447
503
504
        return query;
505
    }
506
    
507
    protected DatabaseQuery buildAddressRecOutCursorQuery() {
508
        
509
        StoredProcedureCall call = new StoredProcedureCall();
510
        call.setProcedureName("PLSQL_P.PLSQL_ADDRESS_REC_CUR_OUT");
511
        call.useNamedCursorOutputAsResultSet("P_ADDRESS");
512
        DataReadQuery query = new DataReadQuery();
513
        query.setCall(call);
514
515
        return query;
516
    }
517
448
    protected DatabaseQuery buildAddressListInOutQuery() {
518
    protected DatabaseQuery buildAddressListInOutQuery() {
449
        PLSQLrecord record = buildAddressRecord();
519
        PLSQLrecord record = buildAddressRecord();
450
        
520
        
Lines 595-600 Link Here
595
665
596
        descriptor.getQueryManager().addQuery("SimpleIn", buildSimpleInQuery());
666
        descriptor.getQueryManager().addQuery("SimpleIn", buildSimpleInQuery());
597
        descriptor.getQueryManager().addQuery("SimpleInDefaults", buildSimpleInDefaultsQuery());
667
        descriptor.getQueryManager().addQuery("SimpleInDefaults", buildSimpleInDefaultsQuery());
668
        descriptor.getQueryManager().addQuery("SimpleInDefaults2", buildSimpleInDefaults2Query());
598
        descriptor.getQueryManager().addQuery("SimpleInFunc", buildSimpleInFuncQuery());
669
        descriptor.getQueryManager().addQuery("SimpleInFunc", buildSimpleInFuncQuery());
599
        descriptor.getQueryManager().addQuery("SimpleOut", buildSimpleOutQuery());
670
        descriptor.getQueryManager().addQuery("SimpleOut", buildSimpleOutQuery());
600
        descriptor.getQueryManager().addQuery("SimpleInOut", buildSimpleInOutQuery());
671
        descriptor.getQueryManager().addQuery("SimpleInOut", buildSimpleInOutQuery());
Lines 613-618 Link Here
613
        descriptor.getQueryManager().addQuery("AddressListInOut", buildAddressListInOutQuery());
684
        descriptor.getQueryManager().addQuery("AddressListInOut", buildAddressListInOutQuery());
614
        descriptor.getQueryManager().addQuery("BadAddressOut", buildBadAddressOutObjectQuery());
685
        descriptor.getQueryManager().addQuery("BadAddressOut", buildBadAddressOutObjectQuery());
615
        descriptor.getQueryManager().addQuery("MissingTypeAddressListOut", buildMissingTypeAddressListOutQuery());
686
        descriptor.getQueryManager().addQuery("MissingTypeAddressListOut", buildMissingTypeAddressListOutQuery());
687
        descriptor.getQueryManager().addQuery("AddressOutCursor", buildAddressOutCursorQuery());
688
        descriptor.getQueryManager().addQuery("AddressRecOutCursor", buildAddressRecOutCursorQuery());
616
        
689
        
617
        descriptor.addFieldOrdering("ADDRESS_ID");
690
        descriptor.addFieldOrdering("ADDRESS_ID");
618
        DirectToFieldMapping idMapping = new DirectToFieldMapping();
691
        DirectToFieldMapping idMapping = new DirectToFieldMapping();
(-)foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/models/plsql/PLSQLSystem.java (-2 / +20 lines)
Lines 34-45 Link Here
34
        } catch (Exception ignore) {}
34
        } catch (Exception ignore) {}
35
        session.executeNonSelectingSQL("CREATE TABLE PLSQL_ADDRESS ("
35
        session.executeNonSelectingSQL("CREATE TABLE PLSQL_ADDRESS ("
36
                + "ADDRESS_ID NUMBER(10) NOT NULL, STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(30), PRIMARY KEY (ADDRESS_ID))");
36
                + "ADDRESS_ID NUMBER(10) NOT NULL, STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(30), PRIMARY KEY (ADDRESS_ID))");
37
        session.executeNonSelectingSQL("INSERT INTO PLSQL_ADDRESS ("
38
                + "ADDRESS_ID, CITY) values (1234, 'Ottawa')");
37
        
39
        
38
        // Procedures
40
        // Procedures
39
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_IN(P_VARCHAR IN VARCHAR2 DEFAULT '', P_BOOLEAN IN BOOLEAN, P_BINARY_INTEGER IN BINARY_INTEGER, "
41
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_IN(P_VARCHAR IN VARCHAR2 DEFAULT '', P_BOOLEAN IN BOOLEAN, P_BINARY_INTEGER IN BINARY_INTEGER, "
40
        		+ "P_DEC IN DEC, P_INT IN INT, P_NATURAL IN NATURAL, P_NATURALN IN NATURALN, "
42
        		+ "P_DEC IN DEC, P_INT IN INT, P_NATURAL IN NATURAL, P_NATURALN IN NATURALN, "
41
        		+ "P_PLS_INTEGER IN PLS_INTEGER, P_POSITIVE IN POSITIVE, P_POSITIVEN IN POSITIVEN, P_SIGNTYPE IN SIGNTYPE, P_NUMBER IN NUMBER) AS "                
43
        		+ "P_PLS_INTEGER IN PLS_INTEGER, P_POSITIVE IN POSITIVE, P_POSITIVEN IN POSITIVEN, P_SIGNTYPE IN SIGNTYPE, P_NUMBER IN NUMBER) AS "                
42
                + "BEGIN NULL; END;");
44
                + "BEGIN NULL; END;");
45
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_IN_DEFAULTS(P_VARCHAR IN VARCHAR2 DEFAULT '', P_BOOLEAN IN BOOLEAN DEFAULT TRUE, P_BINARY_INTEGER IN BINARY_INTEGER DEFAULT 0, "
46
                + "P_DEC IN DEC DEFAULT 0, P_INT IN INT DEFAULT 0, P_NATURAL IN NATURAL DEFAULT 1, P_NATURALN IN NATURALN DEFAULT 1, "
47
                + "P_PLS_INTEGER IN PLS_INTEGER DEFAULT 0, P_POSITIVE IN POSITIVE DEFAULT 1, P_POSITIVEN IN POSITIVEN DEFAULT 1, P_SIGNTYPE IN SIGNTYPE DEFAULT 1, P_NUMBER IN NUMBER DEFAULT 0) AS "                
48
        + "BEGIN NULL; END;");
43
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_OUT(P_VARCHAR OUT VARCHAR2, P_BOOLEAN OUT BOOLEAN, P_BINARY_INTEGER OUT BINARY_INTEGER, "
49
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_OUT(P_VARCHAR OUT VARCHAR2, P_BOOLEAN OUT BOOLEAN, P_BINARY_INTEGER OUT BINARY_INTEGER, "
44
        		+ "P_DEC OUT DEC, P_INT OUT INT, P_NATURAL OUT NATURAL, " //P_NATURALN OUT NATURALN, "
50
        		+ "P_DEC OUT DEC, P_INT OUT INT, P_NATURAL OUT NATURAL, " //P_NATURALN OUT NATURALN, "
45
        		+ "P_PLS_INTEGER OUT PLS_INTEGER, P_POSITIVE OUT POSITIVE, " //P_POSITIVEN OUT POSITIVEN, "
51
        		+ "P_PLS_INTEGER OUT PLS_INTEGER, P_POSITIVE OUT POSITIVE, " //P_POSITIVEN OUT POSITIVEN, "
Lines 74-80 Link Here
74
        session.executeNonSelectingSQL("CREATE OR REPLACE FUNCTION PLSQL_ADDRESS_OUT_FUNC RETURN PLSQL_ADDRESS%ROWTYPE AS "
80
        session.executeNonSelectingSQL("CREATE OR REPLACE FUNCTION PLSQL_ADDRESS_OUT_FUNC RETURN PLSQL_ADDRESS%ROWTYPE AS "
75
                + " P_ADDRESS PLSQL_ADDRESS%ROWTYPE; "
81
                + " P_ADDRESS PLSQL_ADDRESS%ROWTYPE; "
76
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON';  RETURN P_ADDRESS; END;");
82
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON';  RETURN P_ADDRESS; END;");
77
        
83
     
78
        // Types
84
        // Types
79
        try {
85
        try {
80
            session.executeNonSelectingSQL("DROP TYPE PLSQL_P_PLSQL_EMP_REC FORCE");
86
            session.executeNonSelectingSQL("DROP TYPE PLSQL_P_PLSQL_EMP_REC FORCE");
Lines 97-102 Link Here
97
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_EMP_LIST AS VARRAY(255) OF PLSQL_P_PLSQL_EMP_REC");
103
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_EMP_LIST AS VARRAY(255) OF PLSQL_P_PLSQL_EMP_REC");
98
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE PLSQL_P AS \n"
104
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE PLSQL_P AS \n"
99
                    + "TYPE PLSQL_ADDRESS_REC IS RECORD (ADDRESS_ID NUMBER(10), STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(2)); \n"
105
                    + "TYPE PLSQL_ADDRESS_REC IS RECORD (ADDRESS_ID NUMBER(10), STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(2)); \n"
106
                    + "TYPE PLSQL_ADDRESS_CUR IS REF CURSOR RETURN PLSQL_ADDRESS%ROWTYPE; \n"
107
                    + "TYPE PLSQL_ADDRESS_REC_CUR IS REF CURSOR RETURN PLSQL_ADDRESS_REC; \n"
100
                    + "TYPE PLSQL_PHONE_REC IS RECORD (AREA_CODE VARCHAR2(3), P_NUM VARCHAR2(7)); \n"
108
                    + "TYPE PLSQL_PHONE_REC IS RECORD (AREA_CODE VARCHAR2(3), P_NUM VARCHAR2(7)); \n"
101
                    + "TYPE PLSQL_PHONE_LIST IS TABLE OF PLSQL_PHONE_REC INDEX BY BINARY_INTEGER; \n"
109
                    + "TYPE PLSQL_PHONE_LIST IS TABLE OF PLSQL_PHONE_REC INDEX BY BINARY_INTEGER; \n"
102
                    + "TYPE PLSQL_EMP_REC IS RECORD (EMP_ID NUMBER(10), NAME VARCHAR2(30), ACTIVE BOOLEAN, ADDRESS PLSQL_ADDRESS_REC, PHONES PLSQL_PHONE_LIST); \n"
110
                    + "TYPE PLSQL_EMP_REC IS RECORD (EMP_ID NUMBER(10), NAME VARCHAR2(30), ACTIVE BOOLEAN, ADDRESS PLSQL_ADDRESS_REC, PHONES PLSQL_PHONE_LIST); \n"
Lines 115-120 Link Here
115
                    + "PROCEDURE PLSQL_EMP_IN(P_EMP IN PLSQL_EMP_REC, P_CITY IN VARCHAR2); \n"
123
                    + "PROCEDURE PLSQL_EMP_IN(P_EMP IN PLSQL_EMP_REC, P_CITY IN VARCHAR2); \n"
116
                    + "PROCEDURE PLSQL_EMP_OUT(P_EMP OUT PLSQL_EMP_REC, P_CITY OUT VARCHAR2); \n"
124
                    + "PROCEDURE PLSQL_EMP_OUT(P_EMP OUT PLSQL_EMP_REC, P_CITY OUT VARCHAR2); \n"
117
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2); \n"
125
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2); \n"
126
                    + "PROCEDURE PLSQL_ADDRESS_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_CUR); \n"
127
                    + "PROCEDURE PLSQL_ADDRESS_REC_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_REC_CUR); \n"
118
                    + "END PLSQL_P; \n");
128
                    + "END PLSQL_P; \n");
119
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE BODY PLSQL_P AS \n"
129
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE BODY PLSQL_P AS \n"
120
                    + "PROCEDURE PLSQL_CITY_LIST_IN(P_CITY_LIST IN PLSQL_CITY_LIST, P_CITY IN VARCHAR2) AS \n"
130
                    + "PROCEDURE PLSQL_CITY_LIST_IN(P_CITY_LIST IN PLSQL_CITY_LIST, P_CITY IN VARCHAR2) AS \n"
Lines 165-172 Link Here
165
                    	+ "END PLSQL_EMP_OUT; \n"
175
                    	+ "END PLSQL_EMP_OUT; \n"
166
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2) AS \n"
176
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2) AS \n"
167
                    	+ "BEGIN \n"
177
                    	+ "BEGIN \n"
168
                    	+ "P_CITY := 'Nepean'; "
178
                    	+ "P_CITY := 'Nepean'; \n"
169
                    	+ "END PLSQL_EMP_INOUT; \n"
179
                    	+ "END PLSQL_EMP_INOUT; \n"
180
                    + "PROCEDURE PLSQL_ADDRESS_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_CUR) AS \n"
181
                        + "BEGIN \n"
182
                        + "OPEN P_ADDRESS FOR SELECT * FROM PLSQL_ADDRESS; \n"
183
                        + "END PLSQL_ADDRESS_CUR_OUT; \n"
184
                    + "PROCEDURE PLSQL_ADDRESS_REC_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_REC_CUR) AS \n"
185
                        + "BEGIN \n"
186
                        + "OPEN P_ADDRESS FOR SELECT * FROM PLSQL_ADDRESS; \n"
187
                        + "END PLSQL_ADDRESS_REC_CUR_OUT; \n"
170
                    + "END PLSQL_P; \n");
188
                    + "END PLSQL_P; \n");
171
    }
189
    }
172
190
(-)foundation/eclipselink.core.test/src/org/eclipse/persistence/testing/tests/plsql/PLSQLTestModel.java (+26 lines)
Lines 16-21 Link Here
16
import java.util.ArrayList;
16
import java.util.ArrayList;
17
import java.util.Arrays;
17
import java.util.Arrays;
18
import java.util.List;
18
import java.util.List;
19
import java.util.Vector;
19
20
20
import org.eclipse.persistence.exceptions.QueryException;
21
import org.eclipse.persistence.exceptions.QueryException;
21
import org.eclipse.persistence.sessions.DatabaseRecord;
22
import org.eclipse.persistence.sessions.DatabaseRecord;
Lines 121-126 Link Here
121
        suite.addTest(test);
122
        suite.addTest(test);
122
123
123
        args = new ArrayList();
124
        args = new ArrayList();
125
        args.add(null);
126
        args.add(null);
127
        args.add(null);
128
        args.add(null);
129
        args.add(null);
130
        args.add(null);
131
        args.add(null);
132
        args.add(null);
133
        args.add(null);
134
        args.add(null);
135
        args.add(null);
136
        args.add(null);
137
        test = new PLSQLTest("SimpleInDefaults2", Address.class, args);
138
        test.setName("SimpleInDefaults2");
139
        suite.addTest(test);
140
141
        args = new ArrayList();
124
        test = new PLSQLTest("SimpleOut", Address.class, args);
142
        test = new PLSQLTest("SimpleOut", Address.class, args);
125
        test.setName("SimpleOutTest");
143
        test.setName("SimpleOutTest");
126
        suite.addTest(test);
144
        suite.addTest(test);
Lines 299-304 Link Here
299
        test = new PLSQLTest("EmployeeInOutObject", Employee.class, args, result);
317
        test = new PLSQLTest("EmployeeInOutObject", Employee.class, args, result);
300
        test.setName("EmployeeInOutObjectTest");
318
        test.setName("EmployeeInOutObjectTest");
301
        suite.addTest(test);
319
        suite.addTest(test);
320
        
321
        test = new PLSQLTest("AddressOutCursor", Address.class, new ArrayList(), new Vector());
322
        test.setName("AddressOutCursorTest");
323
        suite.addTest(test);
324
        
325
        test = new PLSQLTest("AddressRecOutCursor", Address.class, new ArrayList(), new Vector());
326
        test.setName("AddressRecOutCursorTest");
327
        suite.addTest(test);
302
328
303
        return suite;
329
        return suite;
304
    }
330
    }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/annotations/NamedStoredFunctionQueries.java (-1 / +1 lines)
Lines 23-29 Link Here
23
 * NamedStoredFunctionQuery.
23
 * NamedStoredFunctionQuery.
24
 * 
24
 * 
25
 * @author James
25
 * @author James
26
 * @since Oracle TopLink 11.1.1.0.0 
26
 * @since EclipseLink 2.3
27
 */ 
27
 */ 
28
@Target({TYPE})
28
@Target({TYPE})
29
@Retention(RUNTIME)
29
@Retention(RUNTIME)
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/annotations/StoredProcedureParameter.java (-1 / +6 lines)
Lines 44-51 Link Here
44
     * (Required) The query parameter name.
44
     * (Required) The query parameter name.
45
     */
45
     */
46
    String queryParameter();
46
    String queryParameter();
47
47
    
48
    /**
48
    /**
49
     * (Optional) Define if the parameter is required, or optional and defaulted by the procedure.
50
     */
51
    boolean optional() default false;
52
    
53
    /**
49
     * (Optional) The type of Java class desired back from the procedure, 
54
     * (Optional) The type of Java class desired back from the procedure, 
50
     * this is dependent on the type returned from the procedure.
55
     * this is dependent on the type returned from the procedure.
51
     */
56
     */
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/eis/interactions/EISInteraction.java (-4 / +3 lines)
Lines 287-297 Link Here
287
        writer.write(Helper.cr());
287
        writer.write(Helper.cr());
288
        writer.write("\tinput => [");
288
        writer.write("\tinput => [");
289
        if (!getParameters().isEmpty()) {
289
        if (!getParameters().isEmpty()) {
290
            // Unfortunately vectors cannot print if they have nulls in them...
290
            for (Iterator iterator = getParameters().iterator(); iterator.hasNext();) {
291
            for (Enumeration paramsEnum = getParameters().elements(); paramsEnum.hasMoreElements();) {
291
                Object parameter = iterator.next();
292
                Object parameter = paramsEnum.nextElement();
293
                writer.write(String.valueOf(parameter));
292
                writer.write(String.valueOf(parameter));
294
                if (paramsEnum.hasMoreElements()) {
293
                if (iterator.hasNext()) {
295
                    writer.write(", ");
294
                    writer.write(", ");
296
                } else {
295
                } else {
297
                    writer.write("]");
296
                    writer.write("]");
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/eis/interactions/QueryStringInteraction.java (-4 / +3 lines)
Lines 99-109 Link Here
99
        writer.write(Helper.cr());
99
        writer.write(Helper.cr());
100
        writer.write("\tparameters => [");
100
        writer.write("\tparameters => [");
101
        if (hasParameters()) {
101
        if (hasParameters()) {
102
            // Unfortunately vectors cannot print if they have nulls in them...
102
            for (Iterator iterator = getParameters().iterator(); iterator.hasNext();) {
103
            for (Enumeration paramsEnum = getParameters().elements(); paramsEnum.hasMoreElements();) {
103
                Object parameter = iterator.next();
104
                Object parameter = paramsEnum.nextElement();
105
                writer.write(String.valueOf(parameter));
104
                writer.write(String.valueOf(parameter));
106
                if (paramsEnum.hasMoreElements()) {
105
                if (iterator.hasNext()) {
107
                    writer.write(", ");
106
                    writer.write(", ");
108
                }
107
                }
109
            }
108
            }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/eis/interactions/XQueryInteraction.java (-4 / +3 lines)
Lines 145-155 Link Here
145
        writer.write(Helper.cr());
145
        writer.write(Helper.cr());
146
        writer.write("\tinput => [");
146
        writer.write("\tinput => [");
147
        if (hasParameters()) {
147
        if (hasParameters()) {
148
            // Unfortunately vectors cannot print if they have nulls in them...
148
            for (Iterator iterator = getParameters().iterator(); iterator.hasNext();) {
149
            for (Enumeration paramsEnum = getParameters().elements(); paramsEnum.hasMoreElements();) {
149
                Object parameter = iterator.next();
150
                Object parameter = paramsEnum.nextElement();
151
                writer.write(String.valueOf(parameter));
150
                writer.write(String.valueOf(parameter));
152
                if (paramsEnum.hasMoreElements()) {
151
                if (iterator.hasNext()) {
153
                    writer.write(", ");
152
                    writer.write(", ");
154
                } else {
153
                } else {
155
                    writer.write("]");
154
                    writer.write("]");
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/databaseaccess/DatabaseCall.java (-30 / +41 lines)
Lines 212-218 Link Here
212
        } catch (IOException exception) {
212
        } catch (IOException exception) {
213
            throw ValidationException.fileError(exception);
213
            throw ValidationException.fileError(exception);
214
        }
214
        }
215
        getParameters().addElement(parameter);
215
        getParameters().add(parameter);
216
    }
216
    }
217
217
218
    /**
218
    /**
Lines 343-350 Link Here
343
     * Return 1-based index of out cursor parameter, or -1.
343
     * Return 1-based index of out cursor parameter, or -1.
344
     */
344
     */
345
    public int getCursorOutIndex() {
345
    public int getCursorOutIndex() {
346
        for (int i = 0; i < getParameters().size(); i++) {
346
        int size = getParameters().size();
347
            Object parameter = getParameters().elementAt(i);
347
        for (int i = 0; i < size; i++) {
348
            Object parameter = this.parameters.get(i);
348
            if (parameter instanceof OutputParameterForCallableStatement) {
349
            if (parameter instanceof OutputParameterForCallableStatement) {
349
                if (((OutputParameterForCallableStatement)parameter).isCursor()) {
350
                if (((OutputParameterForCallableStatement)parameter).isCursor()) {
350
                    return i + 1;
351
                    return i + 1;
Lines 424-432 Link Here
424
     */
425
     */
425
    public Vector getOutputRowFields() {
426
    public Vector getOutputRowFields() {
426
        Vector fields = new Vector();
427
        Vector fields = new Vector();
427
        for (int i = 0; i < getParameters().size(); i++) {
428
        int size = getParameters().size();
428
            Integer parameterType = (Integer)getParameterTypes().elementAt(i);
429
        for (int i = 0; i < size; i++) {
429
            Object parameter = getParameters().elementAt(i);
430
            Integer parameterType = this.parameterTypes.get(i);
431
            Object parameter = this.parameters.get(i);
430
            if (parameterType == OUT) {
432
            if (parameterType == OUT) {
431
                fields.add(parameter);
433
                fields.add(parameter);
432
            } else if (parameterType == INOUT) {
434
            } else if (parameterType == INOUT) {
Lines 578-591 Link Here
578
     * Allow pre-printing of the SQL string for fully bound calls, to save from reprinting.
580
     * Allow pre-printing of the SQL string for fully bound calls, to save from reprinting.
579
     * Should be called before translation.
581
     * Should be called before translation.
580
     */
582
     */
583
    @Override
581
    public void prepare(AbstractSession session) {
584
    public void prepare(AbstractSession session) {
582
        if (isPrepared()) {
585
        if (this.isPrepared) {
583
            return;
586
            return;
584
        }
587
        }
585
586
        prepareInternal(session);
588
        prepareInternal(session);
587
589
        this.isPrepared = true;
588
        setIsPrepared(true);
589
    }
590
    }
590
591
591
    /**
592
    /**
Lines 606-613 Link Here
606
            // 2. If there are multiple OUT_CURSOR parameters - throw Validation exception
607
            // 2. If there are multiple OUT_CURSOR parameters - throw Validation exception
607
            int nFirstOutParameterIndex = -1;
608
            int nFirstOutParameterIndex = -1;
608
            boolean hasFoundOutCursor = false;
609
            boolean hasFoundOutCursor = false;
609
            for (int index = 0; index < parameters.size(); index++) {
610
            int size = this.parameters.size();
610
                Integer parameterType = (Integer)parameterTypes.elementAt(index);
611
            for (int index = 0; index < size; index++) {
612
                Integer parameterType = this.parameterTypes.get(index);
611
                if (parameterType == DatasourceCall.OUT_CURSOR) {
613
                if (parameterType == DatasourceCall.OUT_CURSOR) {
612
                    if (hasFoundOutCursor) {
614
                    if (hasFoundOutCursor) {
613
                        // one cursor has been already found
615
                        // one cursor has been already found
Lines 625-642 Link Here
625
                }
627
                }
626
            }
628
            }
627
            if (!hasFoundOutCursor && (nFirstOutParameterIndex >= 0)) {
629
            if (!hasFoundOutCursor && (nFirstOutParameterIndex >= 0)) {
628
                parameterTypes.setElementAt(DatasourceCall.OUT_CURSOR, nFirstOutParameterIndex);
630
                this.parameterTypes.set(nFirstOutParameterIndex, DatasourceCall.OUT_CURSOR);
629
            }
631
            }
630
        }
632
        }
631
633
632
        for (int i = 0; i < getParameters().size(); i++) {
634
        int size = getParameters().size();
633
            Object parameter = getParameters().elementAt(i);
635
        for (int i = 0; i < size; i++) {
634
            Integer parameterType = (Integer)getParameterTypes().elementAt(i);
636
            Object parameter = this.parameters.get(i);
637
            Integer parameterType = this.parameterTypes.get(i);
635
            if (parameterType == MODIFY) {
638
            if (parameterType == MODIFY) {
636
                // in case the field's type is not set, the parameter type is set to CUSTOM_MODIFY.
639
                // in case the field's type is not set, the parameter type is set to CUSTOM_MODIFY.
637
                DatabaseField field = (DatabaseField)parameter;
640
                DatabaseField field = (DatabaseField)parameter;
638
                if ((field.getType() == null) || session.getPlatform().shouldUseCustomModifyForCall(field)) {
641
                if ((field.getType() == null) || session.getPlatform().shouldUseCustomModifyForCall(field)) {
639
                    getParameterTypes().setElementAt(CUSTOM_MODIFY, i);
642
                    this.parameterTypes.set(i, CUSTOM_MODIFY);
640
                }
643
                }
641
            } else if (parameterType == INOUT) {
644
            } else if (parameterType == INOUT) {
642
                // In case there is a type in outField, outParameter is created.
645
                // In case there is a type in outField, outParameter is created.
Lines 672-680 Link Here
672
675
673
                // outParameter contains all the info for registerOutputParameter call.
676
                // outParameter contains all the info for registerOutputParameter call.
674
                OutputParameterForCallableStatement outParameter = new OutputParameterForCallableStatement(outField, session, isCursor);
677
                OutputParameterForCallableStatement outParameter = new OutputParameterForCallableStatement(outField, session, isCursor);
675
                getParameters().setElementAt(outParameter, i);
678
                this.parameters.set(i, outParameter);
676
                // nothing to do during translate method
679
                // nothing to do during translate method
677
                getParameterTypes().setElementAt(LITERAL, i);
680
                this.parameterTypes.set(i, LITERAL);
678
            }
681
            }
679
        }
682
        }
680
        if (this.returnsResultSet == null) {
683
        if (this.returnsResultSet == null) {
Lines 941-954 Link Here
941
     * INTERNAL:
944
     * INTERNAL:
942
     * Allow the call to translate from the translation for predefined calls.
945
     * Allow the call to translate from the translation for predefined calls.
943
     */
946
     */
947
    @Override
944
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
948
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
945
        if (!isPrepared()) {
949
        if (!isPrepared()) {
946
            throw ValidationException.cannotTranslateUnpreparedCall(toString());
950
            throw ValidationException.cannotTranslateUnpreparedCall(toString());
947
        }
951
        }
948
        if (usesBinding(session) && (this.parameters != null)) {
952
        if (usesBinding(session) && (this.parameters != null)) {
949
            boolean hasParameterizedIN = false;
953
            boolean hasParameterizedIN = false;
950
            Vector parameters = getParameters();
954
            List parameters = getParameters();
951
            Vector parameterTypes = getParameterTypes();
955
            List<Integer> parameterTypes = getParameterTypes();
952
            int size = parameters.size();
956
            int size = parameters.size();
953
            Vector parametersValues = new Vector(size);
957
            Vector parametersValues = new Vector(size);
954
            for (int index = 0; index < size; index++) {
958
            for (int index = 0; index < size; index++) {
Lines 1005-1023 Link Here
1005
                    }
1009
                    }
1006
                    // If the value is null, the field is passed as the value so the type can be obtained from the field.
1010
                    // If the value is null, the field is passed as the value so the type can be obtained from the field.
1007
                    if ((value == null) && (field != null)) {
1011
                    if ((value == null) && (field != null)) {
1008
                        value = translationRow.getField(field);
1012
                        if (!this.query.hasNullableArguments() || !this.query.getNullableArguments().contains(field)) {
1009
                        // The field from the row is used, as the calls field may not have the type,
1013
                            value = translationRow.getField(field);
1010
                        // but if the field is missing the calls field may also have the type.
1014
                            // The field from the row is used, as the calls field may not have the type,
1011
                        if (value == null) {
1015
                            // but if the field is missing the calls field may also have the type.
1012
                            value = field;
1016
                            if (value == null) {
1017
                                value = field;
1018
                            }
1019
                            parametersValues.add(value);
1013
                        }
1020
                        }
1021
                    } else {
1022
                        parametersValues.add(value);
1014
                    }
1023
                    }
1015
                    parametersValues.add(value);
1016
                } else if (parameterType == LITERAL) {
1024
                } else if (parameterType == LITERAL) {
1017
                    parametersValues.add(parameter);
1025
                    parametersValues.add(parameter);
1018
                } else if (parameterType == IN) {
1026
                } else if (parameterType == IN) {
1019
                    Object value = getValueForInParameter(parameter, translationRow, modifyRow, session, true);
1027
                    Object value = getValueForInParameter(parameter, translationRow, modifyRow, session, true);
1020
                    parametersValues.add(value);
1028
                    // Returning this means the parameter was optional and should not be included.
1029
                    if (value != this) {
1030
                        parametersValues.add(value);
1031
                    }
1021
                } else if (parameterType == INOUT) {
1032
                } else if (parameterType == INOUT) {
1022
                    Object value = getValueForInOutParameter(parameter, translationRow, modifyRow, session);
1033
                    Object value = getValueForInOutParameter(parameter, translationRow, modifyRow, session);
1023
                    parametersValues.add(value);
1034
                    parametersValues.add(value);
Lines 1045-1052 Link Here
1045
        Writer writer = new CharArrayWriter(queryString.length() + 50);
1056
        Writer writer = new CharArrayWriter(queryString.length() + 50);
1046
        try {
1057
        try {
1047
            // PERF: This method is heavily optimized do not touch anything unless you know "very well" what your doing.
1058
            // PERF: This method is heavily optimized do not touch anything unless you know "very well" what your doing.
1048
            Vector parameters = getParameters();            
1059
            List parameters = getParameters();            
1049
            Vector parametersValues = new Vector(parameters.size());
1060
            List parametersValues = new ArrayList(parameters.size());
1050
            while (lastIndex != -1) {
1061
            while (lastIndex != -1) {
1051
                int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex);
1062
                int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex);
1052
                String token;
1063
                String token;
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/databaseaccess/DatabasePlatform.java (-19 / +24 lines)
Lines 423-430 Link Here
423
            appendLiteralToCallWithBinding(call, writer, literal);
423
            appendLiteralToCallWithBinding(call, writer, literal);
424
        } else {
424
        } else {
425
            int nParametersToAdd = appendParameterInternal(call, writer, literal);
425
            int nParametersToAdd = appendParameterInternal(call, writer, literal);
426
            for(int i=0; i < nParametersToAdd; i++ ) {
426
            for (int i = 0; i < nParametersToAdd; i++) {
427
                ((DatabaseCall)call).getParameterTypes().addElement(DatabaseCall.LITERAL);
427
                ((DatabaseCall)call).getParameterTypes().add(DatabaseCall.LITERAL);
428
            }
428
            }
429
        }
429
        }
430
    }
430
    }
Lines 714-720 Link Here
714
    /**
714
    /**
715
     * Return the proc syntax for this platform.
715
     * Return the proc syntax for this platform.
716
     */
716
     */
717
    public String buildProcedureCallString(StoredProcedureCall call, AbstractSession session) {
717
    public String buildProcedureCallString(StoredProcedureCall call, AbstractSession session, AbstractRecord row) {
718
        StringWriter writer = new StringWriter();
718
        StringWriter writer = new StringWriter();
719
        writer.write(call.getCallHeader(this));
719
        writer.write(call.getCallHeader(this));
720
        writer.write(call.getProcedureName());
720
        writer.write(call.getProcedureName());
Lines 725-748 Link Here
725
        }
725
        }
726
726
727
        int indexFirst = call.getFirstParameterIndexForCallString();
727
        int indexFirst = call.getFirstParameterIndexForCallString();
728
        for (int index = indexFirst; index < call.getParameters().size(); index++) {
728
        int size = call.getParameters().size();
729
            String name = (String)call.getProcedureArgumentNames().elementAt(index);
729
        for (int index = indexFirst; index < size; index++) {
730
            Integer parameterType = (Integer)call.getParameterTypes().elementAt(index);
730
            String name = call.getProcedureArgumentNames().get(index);
731
            if (name != null && shouldPrintStoredProcedureArgumentNameInCall()) {
731
            Object parameter = call.getParameters().get(index);
732
                writer.write(getProcedureArgumentString());
732
            Integer parameterType = call.getParameterTypes().get(index);
733
                writer.write(name);
733
            // If the argument is optional and null, ignore it.
734
                writer.write(getProcedureArgumentSetter());
734
            if (!call.hasOptionalArguments() || !call.getOptionalArguments().contains(parameter) || (row.get(parameter) != null)) {
735
            }
735
                if (name != null && shouldPrintStoredProcedureArgumentNameInCall()) {
736
            writer.write("?");
736
                    writer.write(getProcedureArgumentString());
737
            if (call.isOutputParameterType(parameterType)) {
737
                    writer.write(name);
738
                if (requiresProcedureCallOuputToken()) {
738
                    writer.write(getProcedureArgumentSetter());
739
                    writer.write(" ");
740
                    writer.write(getOutputProcedureToken());
741
                }
739
                }
740
                writer.write("?");
741
                if (call.isOutputParameterType(parameterType)) {
742
                    if (requiresProcedureCallOuputToken()) {
743
                        writer.write(" ");
744
                        writer.write(getOutputProcedureToken());
745
                    }
746
                }
747
                if ((index + 1) < call.getParameters().size()) {
748
                    writer.write(", ");
749
                }
742
            }
750
            }
743
            if ((index + 1) < call.getParameters().size()) {
744
                writer.write(", ");
745
            }
746
        }
751
        }
747
        call.setProcedureArgumentNames(null);
752
        call.setProcedureArgumentNames(null);
748
753
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/databaseaccess/DatasourceCall.java (-30 / +37 lines)
Lines 39-48 Link Here
39
    protected DatabaseQuery query;
39
    protected DatabaseQuery query;
40
40
41
    // The parameters (values) are ordered as they appear in the call.
41
    // The parameters (values) are ordered as they appear in the call.
42
    transient protected Vector parameters;
42
    transient protected List parameters;
43
43
44
    // The parameter types determine if the parameter is a modify, translation or literal type.
44
    // The parameter types determine if the parameter is a modify, translation or literal type.
45
    transient protected Vector parameterTypes;
45
    transient protected List<Integer> parameterTypes;
46
    public static final Integer LITERAL = Integer.valueOf(1);
46
    public static final Integer LITERAL = Integer.valueOf(1);
47
    public static final Integer MODIFY = Integer.valueOf(2);
47
    public static final Integer MODIFY = Integer.valueOf(2);
48
    public static final Integer TRANSLATION = Integer.valueOf(3);
48
    public static final Integer TRANSLATION = Integer.valueOf(3);
Lines 77-85 Link Here
77
     * The parameters are the values in order of occurrence in the SQL statement.
77
     * The parameters are the values in order of occurrence in the SQL statement.
78
     * This is lazy initialized to conserve space on calls that have no parameters.
78
     * This is lazy initialized to conserve space on calls that have no parameters.
79
     */
79
     */
80
    public Vector getParameters() {
80
    public List getParameters() {
81
        if (parameters == null) {
81
        if (parameters == null) {
82
            parameters = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
82
            parameters = new ArrayList();
83
        }
83
        }
84
        return parameters;
84
        return parameters;
85
    }
85
    }
Lines 87-95 Link Here
87
    /**
87
    /**
88
     * The parameter types determine if the parameter is a modify, translation or literal type.
88
     * The parameter types determine if the parameter is a modify, translation or literal type.
89
     */
89
     */
90
    public Vector getParameterTypes() {
90
    public List<Integer> getParameterTypes() {
91
        if (parameterTypes == null) {
91
        if (parameterTypes == null) {
92
            parameterTypes = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
92
            parameterTypes = new ArrayList<Integer>();
93
        }
93
        }
94
        return parameterTypes;
94
        return parameterTypes;
95
    }
95
    }
Lines 97-110 Link Here
97
    /**
97
    /**
98
     * The parameters are the values in order of occurrence in the SQL statement.
98
     * The parameters are the values in order of occurrence in the SQL statement.
99
     */
99
     */
100
    public void setParameters(Vector parameters) {
100
    public void setParameters(List parameters) {
101
        this.parameters = parameters;
101
        this.parameters = parameters;
102
    }
102
    }
103
103
104
    /**
104
    /**
105
     * The parameter types determine if the parameter is a modify, translation or literal type.
105
     * The parameter types determine if the parameter is a modify, translation or literal type.
106
     */
106
     */
107
    public void setParameterTypes(Vector parameterTypes) {
107
    public void setParameterTypes(List<Integer> parameterTypes) {
108
        this.parameterTypes = parameterTypes;
108
        this.parameterTypes = parameterTypes;
109
    }
109
    }
110
110
Lines 130-143 Link Here
130
    /**
130
    /**
131
     * Bound calls can have the SQL pre generated.
131
     * Bound calls can have the SQL pre generated.
132
     */
132
     */
133
    protected boolean isPrepared() {
133
    public boolean isPrepared() {
134
        return isPrepared;
134
        return isPrepared;
135
    }
135
    }
136
136
137
    /**
137
    /**
138
     * Bound calls can have the SQL pre generated.
138
     * Bound calls can have the SQL pre generated.
139
     */
139
     */
140
    protected void setIsPrepared(boolean isPrepared) {
140
    public void setIsPrepared(boolean isPrepared) {
141
        this.isPrepared = isPrepared;
141
        this.isPrepared = isPrepared;
142
    }
142
    }
143
143
Lines 525-532 Link Here
525
        } catch (IOException exception) {
525
        } catch (IOException exception) {
526
            throw ValidationException.fileError(exception);
526
            throw ValidationException.fileError(exception);
527
        }
527
        }
528
        getParameters().addElement(literal);
528
        getParameters().add(literal);
529
        getParameterTypes().addElement(LITERAL);
529
        getParameterTypes().add(LITERAL);
530
    }
530
    }
531
531
532
    /**
532
    /**
Lines 539-546 Link Here
539
        } catch (IOException exception) {
539
        } catch (IOException exception) {
540
            throw ValidationException.fileError(exception);
540
            throw ValidationException.fileError(exception);
541
        }
541
        }
542
        getParameters().addElement(modifyField);
542
        getParameters().add(modifyField);
543
        getParameterTypes().addElement(TRANSLATION);
543
        getParameterTypes().add(TRANSLATION);
544
    }
544
    }
545
545
546
    /**
546
    /**
Lines 553-560 Link Here
553
        } catch (IOException exception) {
553
        } catch (IOException exception) {
554
            throw ValidationException.fileError(exception);
554
            throw ValidationException.fileError(exception);
555
        }
555
        }
556
        getParameters().addElement(modifyField);
556
        getParameters().add(modifyField);
557
        getParameterTypes().addElement(MODIFY);
557
        getParameterTypes().add(MODIFY);
558
    }
558
    }
559
559
560
    /**
560
    /**
Lines 567-574 Link Here
567
        } catch (IOException exception) {
567
        } catch (IOException exception) {
568
            throw ValidationException.fileError(exception);
568
            throw ValidationException.fileError(exception);
569
        }
569
        }
570
        getParameters().addElement(field);
570
        getParameters().add(field);
571
        getParameterTypes().addElement(IN);
571
        getParameterTypes().add(IN);
572
    }
572
    }
573
573
574
    /**
574
    /**
Lines 582-589 Link Here
582
            throw ValidationException.fileError(exception);
582
            throw ValidationException.fileError(exception);
583
        }
583
        }
584
        Object[] inOut = { inoutField, inoutField };
584
        Object[] inOut = { inoutField, inoutField };
585
        getParameters().addElement(inOut);
585
        getParameters().add(inOut);
586
        getParameterTypes().addElement(INOUT);
586
        getParameterTypes().add(INOUT);
587
    }
587
    }
588
588
589
    /**
589
    /**
Lines 596-603 Link Here
596
        } catch (IOException exception) {
596
        } catch (IOException exception) {
597
            throw ValidationException.fileError(exception);
597
            throw ValidationException.fileError(exception);
598
        }
598
        }
599
        getParameters().addElement(outField);
599
        getParameters().add(outField);
600
        getParameterTypes().addElement(OUT);
600
        getParameterTypes().add(OUT);
601
    }
601
    }
602
602
603
    /**
603
    /**
Lines 648-655 Link Here
648
            // PERF: This method is heavily optimized do not touch anything unless you know "very well" what your doing.
648
            // PERF: This method is heavily optimized do not touch anything unless you know "very well" what your doing.
649
            // Must translate field parameters and may get new bound parameters for large data.
649
            // Must translate field parameters and may get new bound parameters for large data.
650
            List parameterFields = getParameters();
650
            List parameterFields = getParameters();
651
            List parameterTypes = getParameterTypes();
651
            List<Integer> parameterTypes = getParameterTypes();
652
            setParameters(org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(parameterFields.size()));
652
            setParameters(NonSynchronizedVector.newInstance(parameterFields.size()));
653
            while (lastIndex != -1) {
653
            while (lastIndex != -1) {
654
                int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex);
654
                int tokenIndex = queryString.indexOf(argumentMarker(), lastIndex);
655
                String token;
655
                String token;
Lines 689-695 Link Here
689
                writer.write(token);
689
                writer.write(token);
690
                if (tokenIndex != -1) {
690
                if (tokenIndex != -1) {
691
                    // Process next parameter.
691
                    // Process next parameter.
692
                    Integer parameterType = (Integer)parameterTypes.get(parameterIndex);
692
                    Integer parameterType = parameterTypes.get(parameterIndex);
693
                    if (parameterType == MODIFY) {
693
                    if (parameterType == MODIFY) {
694
                        DatabaseField field = (DatabaseField)parameterFields.get(parameterIndex);
694
                        DatabaseField field = (DatabaseField)parameterFields.get(parameterIndex);
695
                        Object value = modifyRow.get(field);
695
                        Object value = modifyRow.get(field);
Lines 756-767 Link Here
756
     */
756
     */
757
    protected Object getValueForInParameter(Object parameter, AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session, boolean shouldBind) {
757
    protected Object getValueForInParameter(Object parameter, AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session, boolean shouldBind) {
758
        Object value = parameter;
758
        Object value = parameter;
759
759
        DatabaseField field = null;
760
        boolean isNull = false;
761
        
760
        // Parameter expressions are used for nesting and correct mapping conversion of the value.
762
        // Parameter expressions are used for nesting and correct mapping conversion of the value.
761
        if (parameter instanceof ParameterExpression) {
763
        if (parameter instanceof ParameterExpression) {
762
            value = ((ParameterExpression)parameter).getValue(translationRow, session);
764
            value = ((ParameterExpression)parameter).getValue(translationRow, session);
765
            field = ((ParameterExpression)parameter).getField();
763
        } else if (parameter instanceof DatabaseField) {
766
        } else if (parameter instanceof DatabaseField) {
764
            DatabaseField field = (DatabaseField)parameter;
767
            field = (DatabaseField)parameter;
765
            value = translationRow.get(field);
768
            value = translationRow.get(field);
766
            // Must check for the modify row as well for custom SQL compatibility as only one # is required.
769
            // Must check for the modify row as well for custom SQL compatibility as only one # is required.
767
            if (modifyRow != null) {
770
            if (modifyRow != null) {
Lines 777-783 Link Here
777
                    }
780
                    }
778
                }
781
                }
779
            }
782
            }
780
            if ((value == null) && shouldBind) {
783
            if (value == null && shouldBind) {
784
                isNull = true;
781
                if ((field.getType() != null) ||(field.getSqlType()!= DatabaseField.NULL_SQL_TYPE)){
785
                if ((field.getType() != null) ||(field.getSqlType()!= DatabaseField.NULL_SQL_TYPE)){
782
                    value = field;
786
                    value = field;
783
                } else if (modifyRow != null) {
787
                } else if (modifyRow != null) {
Lines 795-806 Link Here
795
                        value = translationField;
799
                        value = translationField;
796
                    }
800
                    }
797
                }
801
                }
798
            }else {
802
            } else {
799
                if (parameter instanceof ObjectRelationalDatabaseField){
803
                if (parameter instanceof ObjectRelationalDatabaseField){
800
                    value = new InParameterForCallableStatement( value, (DatabaseField)parameter);
804
                    value = new InParameterForCallableStatement(value, (DatabaseField)parameter);
801
                }
805
                }
802
            }
806
            }
803
        }
807
        }
808
        if ((value == null || isNull) && this.query.hasNullableArguments() && this.query.getNullableArguments().contains(field)) {
809
            return this;
810
        }
804
        return value;
811
        return value;
805
    }
812
    }
806
813
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/databaseaccess/QueryStringCall.java (-2 / +2 lines)
Lines 34-45 Link Here
34
     * The parameters are the values in order of occurance in the SQL statement.
34
     * The parameters are the values in order of occurance in the SQL statement.
35
     * This is lazy initialized to conserv space on calls that have no parameters.
35
     * This is lazy initialized to conserv space on calls that have no parameters.
36
     */
36
     */
37
    public Vector getParameters();
37
    public List getParameters();
38
38
39
    /**
39
    /**
40
     * The parameter types determine if the parameter is a modify, translation or litteral type.
40
     * The parameter types determine if the parameter is a modify, translation or litteral type.
41
     */
41
     */
42
    public Vector getParameterTypes();
42
    public List<Integer> getParameterTypes();
43
43
44
    /**
44
    /**
45
     * The parameters are the values in order of occurance in call.
45
     * The parameters are the values in order of occurance in call.
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/ComplexDatabaseType.java (-10 / +7 lines)
Lines 12-22 Link Here
12
 ******************************************************************************/
12
 ******************************************************************************/
13
package org.eclipse.persistence.internal.helper;
13
package org.eclipse.persistence.internal.helper;
14
14
15
//javase imports
16
import java.util.ListIterator;
15
import java.util.ListIterator;
17
import java.util.Vector;
16
import java.util.List;
18
17
19
//EclipseLink imports
20
import org.eclipse.persistence.exceptions.QueryException;
18
import org.eclipse.persistence.exceptions.QueryException;
21
import org.eclipse.persistence.internal.sessions.AbstractRecord;
19
import org.eclipse.persistence.internal.sessions.AbstractRecord;
22
import org.eclipse.persistence.platform.database.DatabasePlatform;
20
import org.eclipse.persistence.platform.database.DatabasePlatform;
Lines 114-120 Link Here
114
        this.javaTypeName = javaTypeName;
112
        this.javaTypeName = javaTypeName;
115
    }
113
    }
116
114
117
    @Override
118
    public ComplexDatabaseType clone() {
115
    public ComplexDatabaseType clone() {
119
        try {
116
        try {
120
            ComplexDatabaseType clone = (ComplexDatabaseType)super.clone();
117
            ComplexDatabaseType clone = (ComplexDatabaseType)super.clone();
Lines 167-173 Link Here
167
    public void buildBeginBlock(StringBuilder sb, PLSQLargument arg, PLSQLStoredProcedureCall call) {
164
    public void buildBeginBlock(StringBuilder sb, PLSQLargument arg, PLSQLStoredProcedureCall call) {
168
        String sql2PlName = call.getSQL2PlName(this);
165
        String sql2PlName = call.getSQL2PlName(this);
169
        if (sql2PlName == null) {
166
        if (sql2PlName == null) {
170
        	// TODO exception
167
            // TODO exception
171
            throw new NullPointerException("no SQL2Pl conversion routine for " + typeName);
168
            throw new NullPointerException("no SQL2Pl conversion routine for " + typeName);
172
        }
169
        }
173
        String target = databaseTypeHelper.buildTarget(arg);
170
        String target = databaseTypeHelper.buildTarget(arg);
Lines 185-191 Link Here
185
    public void buildOutAssignment(StringBuilder sb, PLSQLargument outArg, PLSQLStoredProcedureCall call) {
182
    public void buildOutAssignment(StringBuilder sb, PLSQLargument outArg, PLSQLStoredProcedureCall call) {
186
        String sql2PlName = call.getPl2SQLName(this);
183
        String sql2PlName = call.getPl2SQLName(this);
187
        if (sql2PlName == null) {
184
        if (sql2PlName == null) {
188
        	// TODO: Error.
185
            // TODO: Error.
189
            throw new NullPointerException("no Pl2SQL conversion routine for " + typeName);
186
            throw new NullPointerException("no Pl2SQL conversion routine for " + typeName);
190
        }
187
        }
191
        String target = databaseTypeHelper.buildTarget(outArg);
188
        String target = databaseTypeHelper.buildTarget(outArg);
Lines 200-206 Link Here
200
    }
197
    }
201
198
202
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
199
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
203
    				DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues) {
200
    				DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
204
    	databaseTypeHelper.buildOutputRow(outArg, outputRow,
201
    	databaseTypeHelper.buildOutputRow(outArg, outputRow,
205
                newOutputRow, outputRowFields, outputRowValues);
202
                newOutputRow, outputRowFields, outputRowValues);
206
    }
203
    }
Lines 214-226 Link Here
214
    }
211
    }
215
212
216
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
213
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
217
        AbstractRecord translationRow, DatabasePlatform platform) {
214
            AbstractRecord translationRow, DatabasePlatform platform) {
218
        databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
215
        databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
219
    }
216
    }
220
217
221
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
218
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
222
	        AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
219
	        AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
223
	        Vector translationRowFields, Vector translationRowValues, StoredProcedureCall call) {
220
	        List<DatabaseField> translationRowFields, List translationRowValues, StoredProcedureCall call) {
224
        databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
221
        databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
225
            copyOfTranslationFields, translationRowFields, translationRowValues, call);
222
            copyOfTranslationFields, translationRowFields, translationRowValues, call);
226
    }
223
    }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/helper/DatabaseType.java (-14 / +10 lines)
Lines 13-27 Link Here
13
13
14
package org.eclipse.persistence.internal.helper;
14
package org.eclipse.persistence.internal.helper;
15
15
16
// Javase imports
17
import java.util.Iterator;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.ListIterator;
18
import java.util.ListIterator;
19
import java.util.Vector;
20
import static java.lang.Integer.MIN_VALUE;
19
import static java.lang.Integer.MIN_VALUE;
21
20
22
// Java extension imports
23
24
// EclipseLink imports
25
import org.eclipse.persistence.internal.sessions.AbstractRecord;
21
import org.eclipse.persistence.internal.sessions.AbstractRecord;
26
import org.eclipse.persistence.platform.database.DatabasePlatform;
22
import org.eclipse.persistence.platform.database.DatabasePlatform;
27
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall;
23
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall;
Lines 70-81 Link Here
70
    public void buildOutAssignment(StringBuilder sb, PLSQLargument outArg, PLSQLStoredProcedureCall call);
66
    public void buildOutAssignment(StringBuilder sb, PLSQLargument outArg, PLSQLStoredProcedureCall call);
71
67
72
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
68
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
73
        AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
69
        AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
74
        Vector translationRowFields, Vector translationRowValues,
70
        List<DatabaseField> translationRowFields, List translationRowValues,
75
        StoredProcedureCall call);
71
        StoredProcedureCall call);
76
72
77
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
73
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
78
        DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues);
74
        DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues);
79
75
80
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
76
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
81
        AbstractRecord translationRow, DatabasePlatform platform);
77
        AbstractRecord translationRow, DatabasePlatform platform);
Lines 122-130 Link Here
122
        }
118
        }
123
119
124
        public void translate(PLSQLargument arg, AbstractRecord translationRow,
120
        public void translate(PLSQLargument arg, AbstractRecord translationRow,
125
            AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
121
                AbstractRecord copyOfTranslationRow, List copyOfTranslationFields,
126
            Vector translationRowFields, Vector translationRowValues,
122
                List translationRowFields, List translationRowValues,
127
            StoredProcedureCall call) {
123
                StoredProcedureCall call) {
128
            DatabaseField field = null;
124
            DatabaseField field = null;
129
            for (Iterator i = copyOfTranslationFields.iterator(); i.hasNext(); ) {
125
            for (Iterator i = copyOfTranslationFields.iterator(); i.hasNext(); ) {
130
                DatabaseField f = (DatabaseField)i.next();
126
                DatabaseField f = (DatabaseField)i.next();
Lines 142-154 Link Here
142
            if (arg.scale != MIN_VALUE) {
138
            if (arg.scale != MIN_VALUE) {
143
                field.setScale(arg.scale);
139
                field.setScale(arg.scale);
144
            }
140
            }
145
            translationRowFields.setElementAt(field, arg.inIndex-1);
141
            translationRowFields.set(arg.inIndex - 1, field);
146
            Object value = copyOfTranslationRow.get(field);
142
            Object value = copyOfTranslationRow.get(field);
147
            translationRowValues.setElementAt(value, arg.inIndex-1);
143
            translationRowValues.set(arg.inIndex - 1, value);
148
        }
144
        }
149
145
150
        public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
146
        public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
151
            DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues) {
147
                DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
152
            DatabaseField field = null;
148
            DatabaseField field = null;
153
            for (Iterator i = outputRowFields.iterator(); i.hasNext(); ) {
149
            for (Iterator i = outputRowFields.iterator(); i.hasNext(); ) {
154
                DatabaseField f = (DatabaseField)i.next();
150
                DatabaseField f = (DatabaseField)i.next();
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/queries/CallQueryMechanism.java (-13 / +48 lines)
Lines 61-66 Link Here
61
    }
61
    }
62
62
63
    /**
63
    /**
64
     * Unprepare the call if required.
65
     * Clone and unprepare stored procedure calls, so they can be reprepared with possible different optional arguments.
66
     */
67
    public void unprepare() {
68
        DatabaseQuery query = this.query;
69
        if (hasMultipleCalls()) {
70
            this.calls = ((Vector)this.calls.clone());
71
            int size = this.calls.size();
72
            for (int index = 0; index < size; index++) {
73
                DatabaseCall call = (DatabaseCall)this.calls.get(index);
74
                if (call.isPrepared() && call.isStoredProcedureCall()
75
                        && ((StoredProcedureCall)call).hasOptionalArguments()) {
76
                    call = (DatabaseCall)call.clone();
77
                    call.setIsPrepared(false);
78
                    call.setQuery(query);
79
                    this.calls.set(index, call);
80
                }
81
            }
82
        } else if (this.call != null) {
83
            if (this.call.isPrepared() && this.call.isStoredProcedureCall()
84
                    && ((StoredProcedureCall)this.call).hasOptionalArguments()) {
85
                this.call = (DatabaseCall)this.call.clone();
86
                this.call.setIsPrepared(false);
87
                this.call.setQuery(query);
88
            }
89
        }
90
    }
91
    
92
    /**
64
     * INTERNAL:
93
     * INTERNAL:
65
     * This is different from 'prepareForExecution' in that this is called on the original query,
94
     * This is different from 'prepareForExecution' in that this is called on the original query,
66
     * and the other is called on the copy of the query.
95
     * and the other is called on the copy of the query.
Lines 68-82 Link Here
68
     * will apply to any future execution of this query.
97
     * will apply to any future execution of this query.
69
     */
98
     */
70
    public void prepareCall() throws QueryException {
99
    public void prepareCall() throws QueryException {
71
        DatabaseQuery query = getQuery();
100
        DatabaseQuery query = this.query;
72
        AbstractSession executionSession = query.getExecutionSession();
101
        AbstractSession executionSession = query.getExecutionSession();
73
        if (hasMultipleCalls()) {
102
        if (hasMultipleCalls()) {
74
            if(getQuery().shouldCloneCall()){
103
            if (query.shouldCloneCall()) {
75
                //For glassFish bug2689, the call needs to be cloned when query asks to do so. 
104
                this.calls = ((Vector)this.calls.clone());
76
                calls = ((Vector)getCalls().clone());
77
            }
105
            }
78
            for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
106
            int size = this.calls.size();
79
                DatabaseCall call = (DatabaseCall)callsEnum.nextElement();
107
            for (int index = 0; index < size; index++) {
108
                DatabaseCall call = (DatabaseCall)this.calls.get(index);
109
                if (query.shouldCloneCall()) {
110
                    // Need to clone the call if setting query specific properties on it as the call may be shared.
111
                    call = (DatabaseCall)call.clone();
112
                    call.setQuery(query);
113
                    this.calls.set(index, call);
114
                }
80
                if (!query.shouldIgnoreBindAllParameters()) {
115
                if (!query.shouldIgnoreBindAllParameters()) {
81
                    call.setUsesBinding(query.shouldBindAllParameters());
116
                    call.setUsesBinding(query.shouldBindAllParameters());
82
                }
117
                }
Lines 102-114 Link Here
102
                }
137
                }
103
                call.prepare(executionSession);
138
                call.prepare(executionSession);
104
            }
139
            }
105
        } else if (getCall() != null) {
140
        } else if (this.call != null) {
106
            if (getQuery().shouldCloneCall()){
141
            if (query.shouldCloneCall()) {
107
                //For glassFish bug2689, the call needs to be cloned when query asks to do so. 
142
                // Need to clone the call if setting query specific properties on it as the call may be shared.
108
                call = (DatabaseCall)getDatabaseCall().clone();
143
                this.call = (DatabaseCall)this.call.clone();
109
                setCall(call);
144
                call.setQuery(query);
110
            } 
145
            }
111
            DatabaseCall call = getDatabaseCall();
146
            DatabaseCall call = (DatabaseCall)this.call;
112
            if (!query.shouldIgnoreBindAllParameters()) {
147
            if (!query.shouldIgnoreBindAllParameters()) {
113
                call.setUsesBinding(query.shouldBindAllParameters());
148
                call.setUsesBinding(query.shouldBindAllParameters());
114
            }
149
            }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/queries/DatabaseQueryMechanism.java (+7 lines)
Lines 1059-1062 Link Here
1059
            eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PostUpdateEvent, writeQuery));
1059
            eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PostUpdateEvent, writeQuery));
1060
        }
1060
        }
1061
    }
1061
    }
1062
    
1063
    /**
1064
     * Unprepare the call if required.
1065
     */
1066
    public void unprepare() {
1067
        
1068
    }
1062
}
1069
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/queries/DatasourceCallQueryMechanism.java (-3 / +2 lines)
Lines 418-432 Link Here
418
        DatabaseQuery query = getQuery();
418
        DatabaseQuery query = getQuery();
419
        AbstractSession executionSession = query.getExecutionSession();
419
        AbstractSession executionSession = query.getExecutionSession();
420
        if (hasMultipleCalls()) {
420
        if (hasMultipleCalls()) {
421
            for (Enumeration callsEnum = getCalls().elements(); callsEnum.hasMoreElements();) {
421
            for (DatasourceCall call : (List<DatasourceCall>)getCalls()) {
422
                DatasourceCall call = (DatasourceCall)callsEnum.nextElement();
423
                call.prepare(executionSession);
422
                call.prepare(executionSession);
424
            }
423
            }
425
        } else if (getCall() != null) {
424
        } else if (getCall() != null) {
426
            getCall().prepare(executionSession);
425
            getCall().prepare(executionSession);
427
        }
426
        }
428
    }
427
    }
429
428
    
430
    /**
429
    /**
431
     * Pre-build configure the call.
430
     * Pre-build configure the call.
432
     */
431
     */
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/sessions/factories/ObjectPersistenceRuntimeXMLProject_11_1_1.java (-4 / +4 lines)
Lines 963-972 Link Here
963
        @Override
963
        @Override
964
        public Object getAttributeValueFromObject(Object anObject) throws DescriptorException {
964
        public Object getAttributeValueFromObject(Object anObject) throws DescriptorException {
965
            StoredProcedureCall spc = (StoredProcedureCall)anObject;
965
            StoredProcedureCall spc = (StoredProcedureCall)anObject;
966
            Vector parameterTypes = spc.getParameterTypes();
966
            List parameterTypes = spc.getParameterTypes();
967
            Vector parameters = spc.getParameters();
967
            List parameters = spc.getParameters();
968
            Vector procedureArgumentNames = spc.getProcedureArgumentNames();
968
            List procedureArgumentNames = spc.getProcedureArgumentNames();
969
            Vector storedProcedureArguments = new Vector();
969
            List storedProcedureArguments = new Vector();
970
            for (int i = spc.getFirstParameterIndexForCallString(); i < parameterTypes.size(); i++) {
970
            for (int i = spc.getFirstParameterIndexForCallString(); i < parameterTypes.size(); i++) {
971
                StoredProcedureArgument spa = null;
971
                StoredProcedureArgument spa = null;
972
                Integer direction = (Integer)parameterTypes.get(i);
972
                Integer direction = (Integer)parameterTypes.get(i);
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/jdbc/JDBCTypes.java (-8 / +7 lines)
Lines 13-23 Link Here
13
13
14
package org.eclipse.persistence.platform.database.jdbc;
14
package org.eclipse.persistence.platform.database.jdbc;
15
15
16
//javase imports
17
import java.sql.Array;
16
import java.sql.Array;
18
import java.sql.Struct;
17
import java.sql.Struct;
18
import java.util.List;
19
import java.util.ListIterator;
19
import java.util.ListIterator;
20
import java.util.Vector;
21
import static java.lang.Integer.MIN_VALUE;
20
import static java.lang.Integer.MIN_VALUE;
22
import static java.sql.Types.ARRAY;
21
import static java.sql.Types.ARRAY;
23
import static java.sql.Types.BIGINT;
22
import static java.sql.Types.BIGINT;
Lines 50-57 Link Here
50
import static java.sql.Types.VARBINARY;
49
import static java.sql.Types.VARBINARY;
51
import static java.sql.Types.VARCHAR;
50
import static java.sql.Types.VARCHAR;
52
51
53
//EclipseLink imports
54
import org.eclipse.persistence.internal.helper.ClassConstants;
52
import org.eclipse.persistence.internal.helper.ClassConstants;
53
import org.eclipse.persistence.internal.helper.DatabaseField;
55
import org.eclipse.persistence.internal.helper.DatabaseType;
54
import org.eclipse.persistence.internal.helper.DatabaseType;
56
import org.eclipse.persistence.internal.sessions.AbstractRecord;
55
import org.eclipse.persistence.internal.sessions.AbstractRecord;
57
import org.eclipse.persistence.platform.database.DatabasePlatform;
56
import org.eclipse.persistence.platform.database.DatabasePlatform;
Lines 221-241 Link Here
221
        }
220
        }
222
221
223
        public void translate(PLSQLargument arg, AbstractRecord translationRow,
222
        public void translate(PLSQLargument arg, AbstractRecord translationRow,
224
            AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
223
                AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
225
            Vector translationRowFields, Vector translationRowValues,
224
                List<DatabaseField> translationRowFields, List translationRowValues,
226
            StoredProcedureCall call) {
225
                StoredProcedureCall call) {
227
            databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
226
            databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
228
                copyOfTranslationFields, translationRowFields, translationRowValues, call);
227
                copyOfTranslationFields, translationRowFields, translationRowValues, call);
229
        }
228
        }
230
229
231
        public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
230
        public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
232
            DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues) {
231
                DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
233
            databaseTypeHelper.buildOutputRow(outArg, outputRow,
232
            databaseTypeHelper.buildOutputRow(outArg, outputRow,
234
                newOutputRow, outputRowFields, outputRowValues);
233
                newOutputRow, outputRowFields, outputRowValues);
235
        }
234
        }
236
235
237
        public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
236
        public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
238
            AbstractRecord translationRow, DatabasePlatform platform) {
237
                AbstractRecord translationRow, DatabasePlatform platform) {
239
            databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
238
            databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
240
        }
239
        }
241
240
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/MySQLPlatform.java (-3 / +4 lines)
Lines 24-29 Link Here
24
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
24
import org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter;
25
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
25
import org.eclipse.persistence.internal.expressions.SQLSelectStatement;
26
import org.eclipse.persistence.internal.helper.*;
26
import org.eclipse.persistence.internal.helper.*;
27
import org.eclipse.persistence.internal.sessions.AbstractRecord;
27
import org.eclipse.persistence.internal.sessions.AbstractSession;
28
import org.eclipse.persistence.internal.sessions.AbstractSession;
28
import org.eclipse.persistence.queries.StoredProcedureCall;
29
import org.eclipse.persistence.queries.StoredProcedureCall;
29
import org.eclipse.persistence.queries.ValueReadQuery;
30
import org.eclipse.persistence.queries.ValueReadQuery;
Lines 157-167 Link Here
157
    }
158
    }
158
159
159
    /**
160
    /**
160
     * Return the proc syntax for this platform.
161
     * Return the stored procedure syntax for this platform.
161
     */
162
     */
162
    @Override
163
    @Override
163
    public String buildProcedureCallString(StoredProcedureCall call, AbstractSession session) {
164
    public String buildProcedureCallString(StoredProcedureCall call, AbstractSession session, AbstractRecord row) {
164
        return "{ " + super.buildProcedureCallString(call, session);
165
        return "{ " + super.buildProcedureCallString(call, session, row);
165
    }
166
    }
166
    
167
    
167
    /**
168
    /**
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/annotations/NamedPLSQLStoredFunctionQueries.java (+35 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.database.oracle.annotations;
14
15
import java.lang.annotation.Retention;
16
import java.lang.annotation.Target;
17
18
import static java.lang.annotation.ElementType.TYPE;
19
import static java.lang.annotation.RetentionPolicy.RUNTIME;
20
21
/** 
22
 * A NamedPLSQLStoredFunctionQueries annotation allows the definition of multiple
23
 * NamedPLSQLStoredFunctionQuery.
24
 * 
25
 * @author James
26
 * @since EclipseLink 2.3
27
 */ 
28
@Target({TYPE})
29
@Retention(RUNTIME)
30
public @interface NamedPLSQLStoredFunctionQueries {
31
    /**
32
     * (Required) An array of named PLSQL stored procedure query.
33
     */
34
    NamedPLSQLStoredFunctionQuery[] value();
35
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/annotations/NamedPLSQLStoredFunctionQuery.java (+67 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.database.oracle.annotations;
14
15
import java.lang.annotation.Retention;
16
import java.lang.annotation.Target;
17
18
import static java.lang.annotation.ElementType.TYPE;
19
import static java.lang.annotation.RetentionPolicy.RUNTIME;
20
21
import javax.persistence.QueryHint;
22
23
/** 
24
 * A NamedPLSQLStoredFunctionQuery annotation allows the definition of queries that 
25
 * call PLSQL stored functions as named queries.
26
 * The PLSQL support adds support for complex PLSQL types such as RECORD and TABLE types,
27
 * that are not accessible from JDBC.
28
 * 
29
 * A NamedPLSQLStoredFunctionQuery annotation may be defined on an Entity or
30
 * MappedSuperclass.
31
 * 
32
 * @author James Sutherland
33
 * @since EclipseLink 2.3
34
 */ 
35
@Target({TYPE})
36
@Retention(RUNTIME)
37
public @interface NamedPLSQLStoredFunctionQuery {
38
    /**
39
     * (Required) Unique name that references this stored procedure query.
40
     */
41
    String name();
42
43
    /**
44
     * (Optional) Query hints.
45
     */
46
    QueryHint[] hints() default {};
47
48
    /**
49
     * (Optional) The name of the SQLResultMapping.
50
     */
51
    String resultSetMapping() default "";
52
53
    /**
54
     * (Required) The name of the stored procedure.
55
     */
56
    String functionName();
57
    
58
    /**
59
     * (Optional) Defines the parameters to the stored procedure.
60
     */
61
    PLSQLParameter[] parameters() default {};
62
    
63
    /**
64
     * (Required) Defines the return value of the stored function.
65
     */
66
    PLSQLParameter returnParameter();
67
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/annotations/NamedPLSQLStoredProcedureQueries.java (+35 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.database.oracle.annotations;
14
15
import java.lang.annotation.Retention;
16
import java.lang.annotation.Target;
17
18
import static java.lang.annotation.ElementType.TYPE;
19
import static java.lang.annotation.RetentionPolicy.RUNTIME;
20
21
/** 
22
 * A NamedPLSQLStoredProcedureQueries annotation allows the definition of multiple
23
 * NamedPLSQLStoredProcedureQuery.
24
 * 
25
 * @author James Sutherland
26
 * @since EclipseLink 2.3
27
 */ 
28
@Target({TYPE})
29
@Retention(RUNTIME)
30
public @interface NamedPLSQLStoredProcedureQueries {
31
    /**
32
     * (Required) An array of named PLSQL stored procedure query.
33
     */
34
    NamedPLSQLStoredProcedureQuery[] value();
35
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/annotations/NamedPLSQLStoredProcedureQuery.java (+67 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.database.oracle.annotations;
14
15
import java.lang.annotation.Retention;
16
import java.lang.annotation.Target;
17
18
import static java.lang.annotation.ElementType.TYPE;
19
import static java.lang.annotation.RetentionPolicy.RUNTIME;
20
21
import javax.persistence.QueryHint;
22
23
/** 
24
 * A PLSQLNamedStoredProcedureQuery annotation allows the definition of queries that 
25
 * call PLSQL stored procedures as named queries.
26
 * The PLSQL support adds support for complex PLSQL types such as RECORD and TABLE types,
27
 * that are not accessible from JDBC.
28
 * 
29
 * A PLSQLNamedStoredProcedureQuery annotation may be defined on an Entity or
30
 * MappedSuperclass.
31
 * 
32
 * @author James Sutherland
33
 * @since EclipseLink 2.3
34
 */ 
35
@Target({TYPE})
36
@Retention(RUNTIME)
37
public @interface NamedPLSQLStoredProcedureQuery {
38
    /**
39
     * (Required) Unique name that references this stored procedure query.
40
     */
41
    String name();
42
43
    /**
44
     * (Optional) Query hints.
45
     */
46
    QueryHint[] hints() default {};
47
48
    /**
49
     * (Optional) Refers to the class of the result.
50
     */
51
    Class resultClass() default void.class;
52
53
    /**
54
     * (Optional) The name of the SQLResultMapping.
55
     */
56
    String resultSetMapping() default "";
57
58
    /**
59
     * (Required) The name of the stored procedure.
60
     */
61
    String procedureName();
62
    
63
    /**
64
     * (Optional) Defines the parameters to the stored procedure.
65
     */
66
    PLSQLParameter[] parameters() default {};
67
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/annotations/PLSQLParameter.java (+82 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     Oracle - initial API and implementation
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.database.oracle.annotations;
14
15
import java.lang.annotation.Retention;
16
import java.lang.annotation.Target;
17
18
import org.eclipse.persistence.annotations.Direction;
19
import org.eclipse.persistence.platform.database.jdbc.JDBCTypes;
20
import org.eclipse.persistence.platform.database.oracle.plsql.OraclePLSQLTypes;
21
22
import static java.lang.annotation.RetentionPolicy.RUNTIME;
23
24
import static org.eclipse.persistence.annotations.Direction.IN;
25
26
/** 
27
 * A PLSQLParameter annotation is used within a 
28
 * NamedPLSQLStoredProcedureQuery or PLSQLRecord annotation.
29
 * 
30
 * @see NamedPLSQLStoredProcedureQuery
31
 * @see PLSQLRecord
32
 * @author James Sutherland
33
 * @since EclipseLink 2.3
34
 */ 
35
@Target({})
36
@Retention(RUNTIME)
37
public @interface PLSQLParameter {
38
    /**
39
     * (Optional) The direction of the stored procedure parameter.
40
     */
41
    Direction direction() default IN;
42
43
    /**
44
     * (Optional) Stored procedure parameter name.
45
     */
46
    String name() default "";
47
48
    /**
49
     * (Required) The query parameter name.
50
     */
51
    String queryParameter();
52
    
53
    /**
54
     * (Optional) Define if the parameter is required, or optional and defaulted by the procedure.
55
     */
56
    boolean optional() default false;
57
    
58
    /**
59
     * (Optional) The database data-type for the paramter.
60
     * This either one of the type constants defined in OraclePLSQLTypes, or JDBCTypes,
61
     * or a custom record or table type name.
62
     * @see PLSQLRecord
63
     * @see OraclePLSQLTypes
64
     * @see JDBCTypes
65
     */
66
    String databaseType() default "VARCHAR";
67
    
68
    /**
69
     * (Optional) The max length of the field value.
70
     */
71
    int length() default 255;
72
    
73
    /**
74
     * (Optional) If a numeric, the max scale value.
75
     */
76
    int scale() default 0;
77
78
    /**
79
     * (Optional) If a numeric, the max precision value.
80
     */
81
    int precision() default 0;
82
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/plsql/OraclePLSQLTypes.java (-7 / +6 lines)
Lines 13-24 Link Here
13
13
14
package org.eclipse.persistence.platform.database.oracle.plsql;
14
package org.eclipse.persistence.platform.database.oracle.plsql;
15
15
16
//javse imports
16
import java.util.List;
17
import java.util.ListIterator;
17
import java.util.ListIterator;
18
import java.util.Vector;
19
import static java.sql.Types.OTHER;
18
import static java.sql.Types.OTHER;
20
19
21
// EclipseLink imports
20
import org.eclipse.persistence.internal.helper.DatabaseField;
22
import org.eclipse.persistence.internal.helper.DatabaseType;
21
import org.eclipse.persistence.internal.helper.DatabaseType;
23
import org.eclipse.persistence.internal.helper.SimpleDatabaseType;
22
import org.eclipse.persistence.internal.helper.SimpleDatabaseType;
24
import org.eclipse.persistence.internal.sessions.AbstractRecord;
23
import org.eclipse.persistence.internal.sessions.AbstractRecord;
Lines 187-194 Link Here
187
     * Translate the argument value from the query translation row to call translation row.
186
     * Translate the argument value from the query translation row to call translation row.
188
     */
187
     */
189
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
188
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
190
        AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
189
            AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
191
        Vector translationRowFields, Vector translationRowValues, StoredProcedureCall call) {
190
            List<DatabaseField> translationRowFields, List translationRowValues, StoredProcedureCall call) {
192
        databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
191
        databaseTypeHelper.translate(arg, translationRow, copyOfTranslationRow,
193
            copyOfTranslationFields, translationRowFields, translationRowValues, call);
192
            copyOfTranslationFields, translationRowFields, translationRowValues, call);
194
    }
193
    }
Lines 198-204 Link Here
198
     * Build the query output row from the call output row.
197
     * Build the query output row from the call output row.
199
     */
198
     */
200
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
199
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
201
        DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues) {
200
            DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
202
        databaseTypeHelper.buildOutputRow(outArg, outputRow,
201
        databaseTypeHelper.buildOutputRow(outArg, outputRow,
203
            newOutputRow, outputRowFields, outputRowValues);
202
            newOutputRow, outputRowFields, outputRowValues);
204
    }
203
    }
Lines 208-214 Link Here
208
     * Append the parameter for logging purposes.
207
     * Append the parameter for logging purposes.
209
     */
208
     */
210
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
209
    public void logParameter(StringBuilder sb, Integer direction, PLSQLargument arg,
211
        AbstractRecord translationRow, DatabasePlatform platform) {
210
            AbstractRecord translationRow, DatabasePlatform platform) {
212
        databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
211
        databaseTypeHelper.logParameter(sb, direction, arg, translationRow, platform);
213
    }
212
    }
214
213
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/plsql/PLSQLrecord.java (-7 / +5 lines)
Lines 13-30 Link Here
13
13
14
package org.eclipse.persistence.platform.database.oracle.plsql;
14
package org.eclipse.persistence.platform.database.oracle.plsql;
15
15
16
// javase imports
17
import java.util.ArrayList;
16
import java.util.ArrayList;
18
import java.util.Iterator;
17
import java.util.Iterator;
19
import java.util.List;
18
import java.util.List;
20
import java.util.ListIterator;
19
import java.util.ListIterator;
21
import java.util.Vector;
22
import static java.sql.Types.OTHER;
20
import static java.sql.Types.OTHER;
23
import static java.sql.Types.STRUCT;
21
import static java.sql.Types.STRUCT;
24
22
25
// EclipseLink imports
26
import org.eclipse.persistence.exceptions.QueryException;
23
import org.eclipse.persistence.exceptions.QueryException;
27
import org.eclipse.persistence.internal.helper.ComplexDatabaseType;
24
import org.eclipse.persistence.internal.helper.ComplexDatabaseType;
25
import org.eclipse.persistence.internal.helper.DatabaseField;
28
import org.eclipse.persistence.internal.helper.DatabaseType;
26
import org.eclipse.persistence.internal.helper.DatabaseType;
29
import org.eclipse.persistence.internal.sessions.AbstractRecord;
27
import org.eclipse.persistence.internal.sessions.AbstractRecord;
30
import org.eclipse.persistence.platform.database.DatabasePlatform;
28
import org.eclipse.persistence.platform.database.DatabasePlatform;
Lines 189-197 Link Here
189
    }
187
    }
190
188
191
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
189
    public void translate(PLSQLargument arg, AbstractRecord translationRow,
192
        AbstractRecord copyOfTranslationRow, Vector copyOfTranslationFields,
190
            AbstractRecord copyOfTranslationRow, List<DatabaseField> copyOfTranslationFields,
193
        Vector translationRowFields, Vector translationRowValues,
191
            List<DatabaseField> translationRowFields, List translationRowValues,
194
        StoredProcedureCall call) {
192
            StoredProcedureCall call) {
195
        if (hasCompatibleType()) {
193
        if (hasCompatibleType()) {
196
            super.translate(arg, translationRow, copyOfTranslationRow,
194
            super.translate(arg, translationRow, copyOfTranslationRow,
197
                copyOfTranslationFields, translationRowFields, translationRowValues, call);
195
                copyOfTranslationFields, translationRowFields, translationRowValues, call);
Lines 204-210 Link Here
204
    }
202
    }
205
203
206
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
204
    public void buildOutputRow(PLSQLargument outArg, AbstractRecord outputRow,
207
                DatabaseRecord newOutputRow, Vector outputRowFields, Vector outputRowValues) {
205
                DatabaseRecord newOutputRow, List<DatabaseField> outputRowFields, List outputRowValues) {
208
        if (hasCompatibleType()) {
206
        if (hasCompatibleType()) {
209
            super.buildOutputRow(outArg, outputRow, newOutputRow, outputRowFields, outputRowValues);
207
            super.buildOutputRow(outArg, outputRow, newOutputRow, outputRowFields, outputRowValues);
210
        } else {
208
        } else {
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/plsql/PLSQLStoredFunctionCall.java (-4 / +11 lines)
Lines 15-20 Link Here
15
import static org.eclipse.persistence.internal.helper.DatabaseType.DatabaseTypeHelper.databaseTypeHelper;
15
import static org.eclipse.persistence.internal.helper.DatabaseType.DatabaseTypeHelper.databaseTypeHelper;
16
import static org.eclipse.persistence.internal.helper.Helper.NL;
16
import static org.eclipse.persistence.internal.helper.Helper.NL;
17
17
18
import java.util.List;
19
18
import org.eclipse.persistence.internal.helper.*;
20
import org.eclipse.persistence.internal.helper.*;
19
import org.eclipse.persistence.internal.sessions.AbstractSession;
21
import org.eclipse.persistence.internal.sessions.AbstractSession;
20
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
22
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
Lines 59-64 Link Here
59
     * INTERNAL:
61
     * INTERNAL:
60
     * Return call header for the call string.
62
     * Return call header for the call string.
61
     */
63
     */
64
    @Override
62
    public String getCallHeader(DatabasePlatform platform) {
65
    public String getCallHeader(DatabasePlatform platform) {
63
        return platform.getFunctionCallHeader();
66
        return platform.getFunctionCallHeader();
64
    }
67
    }
Lines 68-73 Link Here
68
     * Return the first index of parameter to be placed inside brackets
71
     * Return the first index of parameter to be placed inside brackets
69
     * in the call string.
72
     * in the call string.
70
     */
73
     */
74
    @Override
71
    public int getFirstParameterIndexForCallString() {
75
    public int getFirstParameterIndexForCallString() {
72
        return 1;
76
        return 1;
73
    }
77
    }
Lines 75-80 Link Here
75
    /**
79
    /**
76
     * INTERNAL:
80
     * INTERNAL:
77
     */
81
     */
82
    @Override
78
    public boolean isStoredFunctionCall() {
83
    public boolean isStoredFunctionCall() {
79
        return true;
84
        return true;
80
    }
85
    }
Lines 82-87 Link Here
82
    /**
87
    /**
83
     * INTERNAL:
88
     * INTERNAL:
84
     */
89
     */
90
    @Override
85
    public void prepareInternal(AbstractSession session) {
91
    public void prepareInternal(AbstractSession session) {
86
        if (session.getPlatform().supportsStoredFunctions()) {
92
        if (session.getPlatform().supportsStoredFunctions()) {
87
            super.prepareInternal(session);
93
            super.prepareInternal(session);
Lines 120-135 Link Here
120
    /**
126
    /**
121
     * INTERNAL Generate portion of the Anonymous PL/SQL block that invokes the target function.
127
     * INTERNAL Generate portion of the Anonymous PL/SQL block that invokes the target function.
122
     */
128
     */
123
    protected void buildProcedureInvocation(StringBuilder sb) {        
129
    @Override
130
    protected void buildProcedureInvocation(StringBuilder sb, List<PLSQLargument> arguments) {
124
        sb.append("  ");
131
        sb.append("  ");
125
        PLSQLargument argument = this.arguments.get(0);
132
        PLSQLargument argument = arguments.get(0);
126
        sb.append(databaseTypeHelper.buildTarget(argument));
133
        sb.append(databaseTypeHelper.buildTarget(argument));
127
        sb.append(" := ");
134
        sb.append(" := ");
128
        sb.append(getProcedureName());
135
        sb.append(getProcedureName());
129
        sb.append("(");
136
        sb.append("(");
130
        int size = this.arguments.size();
137
        int size = arguments.size();
131
        for (int index = 1; index < size; index++) {
138
        for (int index = 1; index < size; index++) {
132
            argument = this.arguments.get(index);
139
            argument = arguments.get(index);
133
            sb.append(argument.name);
140
            sb.append(argument.name);
134
            sb.append("=>");
141
            sb.append("=>");
135
            sb.append(databaseTypeHelper.buildTarget(argument));
142
            sb.append(databaseTypeHelper.buildTarget(argument));
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/database/oracle/plsql/PLSQLStoredProcedureCall.java (-40 / +59 lines)
Lines 566-576 Link Here
566
    /**
566
    /**
567
     * INTERNAL
567
     * INTERNAL
568
     * Generate portion of the Anonymous PL/SQL block that declares the temporary variables
568
     * Generate portion of the Anonymous PL/SQL block that declares the temporary variables
569
     * in the DECLARE section
569
     * in the DECLARE section.
570
     * 
571
     * @param sb
572
     */
570
     */
573
    protected void buildDeclareBlock(StringBuilder sb) {
571
    protected void buildDeclareBlock(StringBuilder sb, List<PLSQLargument> arguments) {
574
        List<PLSQLargument> inArguments = getArguments(arguments, IN);
572
        List<PLSQLargument> inArguments = getArguments(arguments, IN);
575
        List<PLSQLargument> inOutArguments = getArguments(arguments, INOUT);
573
        List<PLSQLargument> inOutArguments = getArguments(arguments, INOUT);
576
        inArguments.addAll(inOutArguments);
574
        inArguments.addAll(inOutArguments);
Lines 891-904 Link Here
891
    /**
889
    /**
892
     * INTERNAL
890
     * INTERNAL
893
     * Generate portion of the Anonymous PL/SQL block with PL/SQL conversion routines as
891
     * Generate portion of the Anonymous PL/SQL block with PL/SQL conversion routines as
894
     * nested functions
892
     * nested functions.
895
     * 
896
     * @param sb
897
     */
893
     */
898
    protected void buildNestedFunctions(StringBuilder stream) {
894
    protected void buildNestedFunctions(StringBuilder stream, List<PLSQLargument> arguments) {
899
        List<String> nestedFunctions = new ArrayList<String>();
895
        List<String> nestedFunctions = new ArrayList<String>();
900
        Set<DatabaseType> processed = new HashSet<DatabaseType>();
896
        Set<DatabaseType> processed = new HashSet<DatabaseType>();
901
        for (PLSQLargument arg : this.arguments) {
897
        for (PLSQLargument arg : arguments) {
902
            DatabaseType type = arg.databaseType;
898
            DatabaseType type = arg.databaseType;
903
            addNestedFunctionsForArgument(nestedFunctions, arg, type, processed);
899
            addNestedFunctionsForArgument(nestedFunctions, arg, type, processed);
904
        }
900
        }
Lines 911-922 Link Here
911
907
912
    /**
908
    /**
913
     * INTERNAL Generate portion of the Anonymous PL/SQL block that assigns fields at the beginning
909
     * INTERNAL Generate portion of the Anonymous PL/SQL block that assigns fields at the beginning
914
     * of the BEGIN block (before invoking the target procedure)
910
     * of the BEGIN block (before invoking the target procedure).
915
     * 
916
     * @param sb
917
     */
911
     */
918
    protected void buildBeginBlock(StringBuilder sb) {
912
    protected void buildBeginBlock(StringBuilder sb, List<PLSQLargument> arguments) {
919
920
        List<PLSQLargument> inArguments = getArguments(arguments, IN);
913
        List<PLSQLargument> inArguments = getArguments(arguments, IN);
921
        inArguments.addAll(getArguments(arguments, INOUT));
914
        inArguments.addAll(getArguments(arguments, INOUT));
922
        for (PLSQLargument arg : inArguments) {
915
        for (PLSQLargument arg : inArguments) {
Lines 925-944 Link Here
925
    }
918
    }
926
919
927
    /**
920
    /**
928
     * INTERNAL Generate portion of the Anonymous PL/SQL block that invokes the target procedure
921
     * INTERNAL Generate portion of the Anonymous PL/SQL block that invokes the target procedure.
929
     * 
930
     * @param sb
931
     */
922
     */
932
    protected void buildProcedureInvocation(StringBuilder sb) {
923
    protected void buildProcedureInvocation(StringBuilder sb, List<PLSQLargument> arguments) {
933
        
934
        sb.append("  ");
924
        sb.append("  ");
935
        sb.append(getProcedureName());
925
        sb.append(getProcedureName());
936
        sb.append("(");
926
        sb.append("(");
937
        int size = arguments.size(), idx = 1;
927
        int size = arguments.size(), idx = 1;
938
        for (PLSQLargument arg : arguments) {
928
        for (PLSQLargument argument : arguments) {
939
            sb.append(arg.name);
929
            sb.append(argument.name);
940
            sb.append("=>");
930
            sb.append("=>");
941
            sb.append(databaseTypeHelper.buildTarget(arg));
931
            sb.append(databaseTypeHelper.buildTarget(argument));
942
            if (idx < size) {
932
            if (idx < size) {
943
                sb.append(", ");
933
                sb.append(", ");
944
                idx++;
934
                idx++;
Lines 950-960 Link Here
950
940
951
    /**
941
    /**
952
     * INTERNAL Generate portion of the Anonymous PL/SQL block after the target procedures has been
942
     * INTERNAL Generate portion of the Anonymous PL/SQL block after the target procedures has been
953
     * invoked and OUT parameters must be handled
943
     * invoked and OUT parameters must be handled.
954
     * 
955
     * @param sb
956
     */
944
     */
957
    protected void buildOutAssignments(StringBuilder sb) {
945
    protected void buildOutAssignments(StringBuilder sb, List<PLSQLargument> arguments) {
958
        List<PLSQLargument> outArguments = getArguments(arguments, OUT);
946
        List<PLSQLargument> outArguments = getArguments(arguments, OUT);
959
        outArguments.addAll(getArguments(arguments, INOUT));
947
        outArguments.addAll(getArguments(arguments, INOUT));
960
        for (PLSQLargument arg : outArguments) {
948
        for (PLSQLargument arg : outArguments) {
Lines 970-986 Link Here
970
        // build any and all required type conversion routines for
958
        // build any and all required type conversion routines for
971
        // complex PL/SQL types in packages
959
        // complex PL/SQL types in packages
972
        this.typesInfo = new HashMap<String, TypeInfo>();
960
        this.typesInfo = new HashMap<String, TypeInfo>();
961
        // Rest parameters to be recomputed if being reprepared.
962
        this.parameters = null;
973
        // create a copy of the arguments re-ordered with different indices
963
        // create a copy of the arguments re-ordered with different indices
974
        assignIndices();
964
        assignIndices();
965
        
966
        // Filter out any optional arguments that are null.
967
        List<PLSQLargument> specifiedArguments = this.arguments;
968
        AbstractRecord row = getQuery().getTranslationRow();
969
        if ((row != null) && hasOptionalArguments()) {
970
            for (PLSQLargument argument : this.arguments) {
971
                DatabaseField queryArgument = new DatabaseField(argument.name);
972
                if (this.optionalArguments.contains(queryArgument) && (row.get(queryArgument) == null)) {
973
                    if (specifiedArguments == this.arguments) {
974
                        specifiedArguments = new ArrayList<PLSQLargument>(this.arguments);
975
                    }
976
                    specifiedArguments.remove(argument);
977
                }
978
            }
979
        }
975
        // build the Anonymous PL/SQL block in sections
980
        // build the Anonymous PL/SQL block in sections
976
        StringBuilder sb = new StringBuilder();
981
        StringBuilder sb = new StringBuilder();
977
        sb.append(BEGIN_DECLARE_BLOCK);
982
        if (!specifiedArguments.isEmpty()) {
978
        buildDeclareBlock(sb);
983
            sb.append(BEGIN_DECLARE_BLOCK);
979
        buildNestedFunctions(sb);
984
            buildDeclareBlock(sb, specifiedArguments);
985
            buildNestedFunctions(sb, specifiedArguments);
986
        }
980
        sb.append(BEGIN_BEGIN_BLOCK);
987
        sb.append(BEGIN_BEGIN_BLOCK);
981
        buildBeginBlock(sb);
988
        buildBeginBlock(sb, specifiedArguments);
982
        buildProcedureInvocation(sb);
989
        buildProcedureInvocation(sb, specifiedArguments);
983
        buildOutAssignments(sb);
990
        buildOutAssignments(sb, specifiedArguments);
984
        sb.append(END_BEGIN_BLOCK);
991
        sb.append(END_BEGIN_BLOCK);
985
        setSQLStringInternal(sb.toString());
992
        setSQLStringInternal(sb.toString());
986
        super.prepareInternalParameters(session);
993
        super.prepareInternalParameters(session);
Lines 992-1005 Link Here
992
     * This handles expanding and re-ordering parameters.          
999
     * This handles expanding and re-ordering parameters.          
993
     */                                                            
1000
     */                                                            
994
    @Override
1001
    @Override
995
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow,
1002
    public void translate(AbstractRecord translationRow, AbstractRecord modifyRow, AbstractSession session) {
996
        AbstractSession session) {
997
        // re-order elements in translationRow to conform to re-ordered indices
1003
        // re-order elements in translationRow to conform to re-ordered indices
998
        AbstractRecord copyOfTranslationRow = translationRow.clone();
1004
        AbstractRecord copyOfTranslationRow = translationRow.clone();
999
        int len = copyOfTranslationRow.size();
1005
        int len = copyOfTranslationRow.size();
1000
        Vector copyOfTranslationFields = copyOfTranslationRow.getFields();
1006
        List<DatabaseField> copyOfTranslationFields = copyOfTranslationRow.getFields();
1001
        translationRow.clear();
1007
        translationRow.clear();
1002
        Vector translationRowFields = translationRow.getFields();
1008
        Vector<DatabaseField> translationRowFields = translationRow.getFields();
1003
        translationRowFields.setSize(len);
1009
        translationRowFields.setSize(len);
1004
        Vector translationRowValues = translationRow.getValues();
1010
        Vector translationRowValues = translationRow.getValues();
1005
        translationRowValues.setSize(len);
1011
        translationRowValues.setSize(len);
Lines 1055-1062 Link Here
1055
        sb.append(Helper.cr());
1061
        sb.append(Helper.cr());
1056
        sb.append(INDENT);
1062
        sb.append(INDENT);
1057
        sb.append("bind => [");
1063
        sb.append("bind => [");
1058
        List<PLSQLargument> inArguments = getArguments(arguments, IN);
1064
        List<PLSQLargument> specifiedArguments = this.arguments;
1059
        inArguments.addAll(getArguments(arguments, INOUT));
1065
        AbstractRecord row = getQuery().getTranslationRow();
1066
        if ((row != null) && hasOptionalArguments()) {
1067
            for (PLSQLargument argument : this.arguments) {
1068
                DatabaseField queryArgument = new DatabaseField(argument.name);
1069
                if (this.optionalArguments.contains(queryArgument) && (row.get(queryArgument) == null)) {
1070
                    if (specifiedArguments == this.arguments) {
1071
                        specifiedArguments = new ArrayList<PLSQLargument>(this.arguments);
1072
                    }
1073
                    specifiedArguments.remove(argument);
1074
                }
1075
            }
1076
        }
1077
        List<PLSQLargument> inArguments = getArguments(specifiedArguments, IN);
1078
        inArguments.addAll(getArguments(specifiedArguments, INOUT));
1060
        Collections.sort(inArguments, new Comparator<PLSQLargument>() {
1079
        Collections.sort(inArguments, new Comparator<PLSQLargument>() {
1061
            public int compare(PLSQLargument o1, PLSQLargument o2) {
1080
            public int compare(PLSQLargument o1, PLSQLargument o2) {
1062
                return o1.inIndex - o2.inIndex;
1081
                return o1.inIndex - o2.inIndex;
Lines 1070-1077 Link Here
1070
                sb.append(", ");
1089
                sb.append(", ");
1071
            }
1090
            }
1072
        }
1091
        }
1073
        List<PLSQLargument> outArguments = getArguments(arguments, OUT);
1092
        List<PLSQLargument> outArguments = getArguments(specifiedArguments, OUT);
1074
        outArguments.addAll(getArguments(arguments, INOUT));
1093
        outArguments.addAll(getArguments(specifiedArguments, INOUT));
1075
        Collections.sort(outArguments, new Comparator<PLSQLargument>() {
1094
        Collections.sort(outArguments, new Comparator<PLSQLargument>() {
1076
            public int compare(PLSQLargument o1, PLSQLargument o2) {
1095
            public int compare(PLSQLargument o1, PLSQLargument o2) {
1077
                return o1.outIndex - o2.outIndex;
1096
                return o1.outIndex - o2.outIndex;
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/DatabaseQuery.java (-16 / +89 lines)
Lines 176-181 Link Here
176
     * non-pre SQL generated queries.
176
     * non-pre SQL generated queries.
177
     */
177
     */
178
    protected boolean shouldPrepare;
178
    protected boolean shouldPrepare;
179
    
180
    /**
181
     * List of arguments to check for null.
182
     * If any are null, the query needs to be re-prepared.
183
     */
184
    protected List<DatabaseField> nullableArguments;
179
185
180
    /** Bind all arguments to the SQL statement. */
186
    /** Bind all arguments to the SQL statement. */
181
187
Lines 359-368 Link Here
359
     * executeQuery()
365
     * executeQuery()
360
     */
366
     */
361
    public void addArgument(String argumentName) {
367
    public void addArgument(String argumentName) {
362
        // CR#3545 - Changed the default argument type to make argument types
368
        addArgument(argumentName, Object.class);
363
        // work more consistently
364
        // with the SDK
365
        addArgument(argumentName, java.lang.Object.class);
366
    }
369
    }
367
370
368
    /**
371
    /**
Lines 373-381 Link Here
373
     * identically named queries are used but with different argument lists.
376
     * identically named queries are used but with different argument lists.
374
     */
377
     */
375
    public void addArgument(String argumentName, Class type) {
378
    public void addArgument(String argumentName, Class type) {
379
        addArgument(argumentName, type, false);
380
    }
381
382
    /**
383
     * PUBLIC: Add the argument named argumentName and its class type. This will
384
     * cause the translation of references of argumentName in the receiver's
385
     * expression, with the value of the argument as supplied to the query in
386
     * order from executeQuery(). Specifying the class type is important if
387
     * identically named queries are used but with different argument lists.
388
     * If the argument can be null, and null must be treated differently in the
389
     * generated SQL, then nullable should be set to true.
390
     */
391
    public void addArgument(String argumentName, Class type, boolean nullable) {
376
        getArguments().add(argumentName);
392
        getArguments().add(argumentName);
377
        getArgumentTypes().add(type);
393
        getArgumentTypes().add(type);
378
        getArgumentTypeNames().add(type.getName());
394
        getArgumentTypeNames().add(type.getName());
395
        if (nullable) {
396
            getNullableArguments().add(new DatabaseField(argumentName));
397
        }
379
    }
398
    }
380
399
381
    /**
400
    /**
Lines 597-622 Link Here
597
        try {
616
        try {
598
            DatabaseQuery cloneQuery = (DatabaseQuery) super.clone();
617
            DatabaseQuery cloneQuery = (DatabaseQuery) super.clone();
599
618
600
            // Keep a reference back to the original source query.
601
            cloneQuery.sourceMapping = this.sourceMapping;
602
603
            // partial fix for 3054240
619
            // partial fix for 3054240
604
            // need to pay attention to other components of the query, too MWN
620
            // need to pay attention to other components of the query, too MWN
605
            if (cloneQuery.properties != null) {
621
            if (cloneQuery.properties != null) {
606
                if (cloneQuery.properties.isEmpty()) {
622
                if (cloneQuery.properties.isEmpty()) {
607
                    cloneQuery.setProperties(null);
623
                    cloneQuery.properties = null;
608
                } else {
624
                } else {
609
                    cloneQuery.setProperties(new HashMap(getProperties()));
625
                    cloneQuery.properties = new HashMap(this.properties);
610
                }
626
                }
611
            }
627
            }
612
628
613
            // bug 3524620: now that the query mechanism is lazy-init'd,
629
            // bug 3524620: now that the query mechanism is lazy-init'd,
614
            // only clone the query mechanism if we have one.
630
            // only clone the query mechanism if we have one.
615
            if (hasQueryMechanism()) {
631
            if (this.queryMechanism != null) {
616
                cloneQuery.setQueryMechanism(getQueryMechanism().clone(cloneQuery));
632
                cloneQuery.queryMechanism = this.queryMechanism.clone(cloneQuery);
617
            }
633
            }
618
            cloneQuery.setIsPrepared(isPrepared());// Setting some things will
634
            cloneQuery.isPrepared = this.isPrepared; // Setting some things may trigger unprepare.
619
            // trigger unprepare.
620
            return cloneQuery;
635
            return cloneQuery;
621
        } catch (CloneNotSupportedException e) {
636
        } catch (CloneNotSupportedException e) {
622
            return null;
637
            return null;
Lines 775-781 Link Here
775
        // so the query keeps track if it has been cloned already.
790
        // so the query keeps track if it has been cloned already.
776
        queryToExecute = session.prepareDatabaseQuery(queryToExecute);
791
        queryToExecute = session.prepareDatabaseQuery(queryToExecute);
777
792
778
        if (queryToExecute.shouldPrepare()) {
793
        boolean prepare = queryToExecute.shouldPrepare(translationRow);
794
        if (prepare) {
779
            queryToExecute.checkPrepare(session, translationRow);
795
            queryToExecute.checkPrepare(session, translationRow);
780
        }
796
        }
781
797
Lines 791-797 Link Here
791
807
792
        // If the prepare has been disable the clone is prepare dynamically to
808
        // If the prepare has been disable the clone is prepare dynamically to
793
        // not parameterize the SQL.
809
        // not parameterize the SQL.
794
        if (!queryToExecute.shouldPrepare()) {
810
        if (!prepare) {
811
            queryToExecute.setIsPrepared(false);
812
            queryToExecute.setTranslationRow(translationRow);
795
            queryToExecute.checkPrepare(session, translationRow);
813
            queryToExecute.checkPrepare(session, translationRow);
796
        }
814
        }
797
        queryToExecute.setSession(session);
815
        queryToExecute.setSession(session);
Lines 1642-1647 Link Here
1642
        this.cascadePolicy = query.cascadePolicy;
1660
        this.cascadePolicy = query.cascadePolicy;
1643
        this.flushOnExecute = query.flushOnExecute;
1661
        this.flushOnExecute = query.flushOnExecute;
1644
        this.arguments = query.arguments;
1662
        this.arguments = query.arguments;
1663
        this.nullableArguments = query.nullableArguments;
1645
        this.argumentTypes = query.argumentTypes;
1664
        this.argumentTypes = query.argumentTypes;
1646
        this.argumentTypeNames = query.argumentTypeNames;
1665
        this.argumentTypeNames = query.argumentTypeNames;
1647
        this.argumentValues = query.argumentValues;
1666
        this.argumentValues = query.argumentValues;
Lines 1658-1663 Link Here
1658
        this.shouldRetrieveBypassCache = query.shouldRetrieveBypassCache;
1677
        this.shouldRetrieveBypassCache = query.shouldRetrieveBypassCache;
1659
        this.shouldStoreBypassCache = query.shouldStoreBypassCache;
1678
        this.shouldStoreBypassCache = query.shouldStoreBypassCache;
1660
        this.parameterDelimiter = query.parameterDelimiter;
1679
        this.parameterDelimiter = query.parameterDelimiter;
1680
        this.shouldCloneCall = query.shouldCloneCall;
1681
        this.partitioningPolicy = query.partitioningPolicy;
1661
    }
1682
    }
1662
1683
1663
    /**
1684
    /**
Lines 1968-1975 Link Here
1968
     */
1989
     */
1969
    public void setIsPrepared(boolean isPrepared) {
1990
    public void setIsPrepared(boolean isPrepared) {
1970
        this.isPrepared = isPrepared;
1991
        this.isPrepared = isPrepared;
1971
        if (!isPrepared){
1992
        if (!isPrepared) {
1972
            this.isCustomQueryUsed = null;
1993
            this.isCustomQueryUsed = null;
1994
            if (this.queryMechanism != null) {
1995
                this.queryMechanism.unprepare();
1996
            }
1973
        }
1997
        }
1974
    }
1998
    }
1975
1999
Lines 2366-2371 Link Here
2366
    public boolean shouldPrepare() {
2390
    public boolean shouldPrepare() {
2367
        return shouldPrepare;
2391
        return shouldPrepare;
2368
    }
2392
    }
2393
    
2394
    /**
2395
     * INTERNAL:
2396
     * Check if the query should be prepared, or dynamic, depending on the arguments.
2397
     * This allows null parameters to affect the SQL, such as stored procedure default values,
2398
     * or IS NULL, or insert defaults.
2399
     */
2400
    public boolean shouldPrepare(AbstractRecord translationRow) {
2401
        if (!this.shouldPrepare) {
2402
            return false;
2403
        }
2404
        if (this.nullableArguments != null) {
2405
            for (DatabaseField argument : this.nullableArguments) {
2406
                if (translationRow.get(argument) == null) {
2407
                    return false;
2408
                }
2409
            }
2410
        }
2411
        return true;
2412
    }
2369
2413
2370
    /**
2414
    /**
2371
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
2415
     * ADVANCED: JPA flag used to control the behavior of the shared cache. This
Lines 2487-2490 Link Here
2487
    public void setBatchObjects(Map<Object, Object> batchObjects) {
2531
    public void setBatchObjects(Map<Object, Object> batchObjects) {
2488
        setProperty(BATCH_FETCH_PROPERTY, batchObjects);
2532
        setProperty(BATCH_FETCH_PROPERTY, batchObjects);
2489
    }
2533
    }
2534
2535
    /**
2536
     * INTERNAL:
2537
     * Return if the query has any nullable arguments.
2538
     */
2539
    public boolean hasNullableArguments() {
2540
        return (this.nullableArguments != null) && !this.nullableArguments.isEmpty();
2541
    }
2542
2543
    /**
2544
     * INTERNAL:
2545
     * Return the list of arguments to check for null.
2546
     * If any are null, the query needs to be re-prepared.
2547
     */
2548
    public List<DatabaseField> getNullableArguments() {
2549
        if (this.nullableArguments == null) {
2550
            this.nullableArguments = new ArrayList<DatabaseField>();
2551
        }
2552
        return nullableArguments;
2553
    }
2554
2555
    /**
2556
     * INTERNAL:
2557
     * Set the list of arguments to check for null.
2558
     * If any are null, the query needs to be re-prepared.
2559
     */
2560
    public void setNullableArguments(List<DatabaseField> nullableArguments) {
2561
        this.nullableArguments = nullableArguments;
2562
    }
2490
}
2563
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/DataReadQuery.java (-7 / +16 lines)
Lines 88-93 Link Here
88
     * It will cause the original to be cached in the query results if the query
88
     * It will cause the original to be cached in the query results if the query
89
     * is set to do so.
89
     * is set to do so.
90
     */
90
     */
91
    @Override
91
    public void cacheResult(Object results) {
92
    public void cacheResult(Object results) {
92
        setTemporaryCachedQueryResults(results);
93
        setTemporaryCachedQueryResults(results);
93
    }
94
    }
Lines 96-104 Link Here
96
     * INTERNAL:
97
     * INTERNAL:
97
     * Clone the query.
98
     * Clone the query.
98
     */
99
     */
100
    @Override
99
    public Object clone() {
101
    public Object clone() {
100
        DataReadQuery cloneQuery = (DataReadQuery)super.clone();
102
        DataReadQuery cloneQuery = (DataReadQuery)super.clone();
101
        cloneQuery.setContainerPolicy(getContainerPolicy().clone(cloneQuery));
103
        cloneQuery.containerPolicy = this.containerPolicy.clone(cloneQuery);
102
        return cloneQuery;
104
        return cloneQuery;
103
    }
105
    }
104
106
Lines 107-116 Link Here
107
     * Execute the query. If there are cached results return those.
109
     * Execute the query. If there are cached results return those.
108
     * This must override the super to support result caching.
110
     * This must override the super to support result caching.
109
     *
111
     *
110
     * @param aSession - the session in which the receiver will be executed.
112
     * @param session - the session in which the receiver will be executed.
111
     * @return An object or vector, the result of executing the query.
113
     * @return An object or collection, the result of executing the query.
112
     * @exception DatabaseException - an error has occurred on the database
114
     * @exception DatabaseException - an error has occurred on the database
113
     */
115
     */
116
    @Override
114
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {
117
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {
115
        if (shouldCacheQueryResults()) {
118
        if (shouldCacheQueryResults()) {
116
            if (this.containerPolicy.overridesRead()) {
119
            if (this.containerPolicy.overridesRead()) {
Lines 141-146 Link Here
141
     * @exception DatabaseException an error has occurred on the database
144
     * @exception DatabaseException an error has occurred on the database
142
     * @return a collection or cursor of Records representing the result set
145
     * @return a collection or cursor of Records representing the result set
143
     */
146
     */
147
    @Override
144
    public Object executeDatabaseQuery() throws DatabaseException {
148
    public Object executeDatabaseQuery() throws DatabaseException {
145
        if (getContainerPolicy().overridesRead()) {
149
        if (getContainerPolicy().overridesRead()) {
146
            return getContainerPolicy().execute();
150
            return getContainerPolicy().execute();
Lines 162-167 Link Here
162
     * INTERNAL:
166
     * INTERNAL:
163
     * Build the result value for the row.
167
     * Build the result value for the row.
164
     */
168
     */
169
    @Override
165
    public Object buildObject(AbstractRecord row) {
170
    public Object buildObject(AbstractRecord row) {
166
        if (this.resultType == AUTO) {
171
        if (this.resultType == AUTO) {
167
            List values = row.getValues();
172
            List values = row.getValues();
Lines 230-236 Link Here
230
    /**
235
    /**
231
     * PUBLIC:
236
     * PUBLIC:
232
     * Return the query's ContainerPolicy.
237
     * Return the query's ContainerPolicy.
233
     * @return org.eclipse.persistence.internal.queries.ContainerPolicy
234
     */
238
     */
235
    public ContainerPolicy getContainerPolicy() {
239
    public ContainerPolicy getContainerPolicy() {
236
        return containerPolicy;
240
        return containerPolicy;
Lines 240-245 Link Here
240
     * PUBLIC:
244
     * PUBLIC:
241
     * Return if this is a data read query.
245
     * Return if this is a data read query.
242
     */
246
     */
247
    @Override
243
    public boolean isDataReadQuery() {
248
    public boolean isDataReadQuery() {
244
        return true;
249
        return true;
245
    }
250
    }
Lines 248-257 Link Here
248
     * INTERNAL:
253
     * INTERNAL:
249
     * Prepare the receiver for execution in a session.
254
     * Prepare the receiver for execution in a session.
250
     */
255
     */
256
    @Override
251
    protected void prepare() {
257
    protected void prepare() {
252
        super.prepare();
258
        super.prepare();
253
        getContainerPolicy().prepare(this, getSession());
259
        this.containerPolicy.prepare(this, this.session);
254
        if (getContainerPolicy().overridesRead()) {
260
        if (this.containerPolicy.overridesRead()) {
255
            return;
261
            return;
256
        }
262
        }
257
        getQueryMechanism().prepareExecuteSelect();
263
        getQueryMechanism().prepareExecuteSelect();
Lines 261-274 Link Here
261
     * INTERNAL:
267
     * INTERNAL:
262
     * Prepare the receiver for execution in a session.
268
     * Prepare the receiver for execution in a session.
263
     */
269
     */
270
    @Override
264
    public void prepareForExecution() throws QueryException {
271
    public void prepareForExecution() throws QueryException {
265
        super.prepareForExecution();
272
        super.prepareForExecution();
266
        getContainerPolicy().prepareForExecution();
273
        this.containerPolicy.prepareForExecution();
267
    }
274
    }
268
275
269
    /**
276
    /**
270
     * INTERNAL:
277
     * INTERNAL:
278
     * Used by RemoteSession.
271
     */
279
     */
280
    @Override
272
    public Object remoteExecute() {
281
    public Object remoteExecute() {
273
        if (getContainerPolicy().overridesRead()) {
282
        if (getContainerPolicy().overridesRead()) {
274
            return getContainerPolicy().remoteExecute();
283
            return getContainerPolicy().remoteExecute();
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ObjectLevelReadQuery.java (-18 / +53 lines)
Lines 251-256 Link Here
251
     * Return if the query is equal to the other.
251
     * Return if the query is equal to the other.
252
     * This is used to allow dynamic expression query SQL to be cached.
252
     * This is used to allow dynamic expression query SQL to be cached.
253
     */
253
     */
254
    @Override
254
    public boolean equals(Object object) {
255
    public boolean equals(Object object) {
255
        if (this == object) {
256
        if (this == object) {
256
            return true;
257
            return true;
Lines 302-309 Link Here
302
        } else if (query.hasOrderByExpressions()) {
303
        } else if (query.hasOrderByExpressions()) {
303
            return false;
304
            return false;
304
        }
305
        }
305
        return ((getReferenceClass() == query.getReferenceClass()) || ((getReferenceClass() != null) && getReferenceClass().equals(query.getReferenceClass())))
306
        if (! ((this.referenceClass == query.referenceClass) || ((this.referenceClass != null) && this.referenceClass.equals(query.referenceClass)))) {
306
            && ((getSelectionCriteria() == query.getSelectionCriteria()) || ((getSelectionCriteria() != null) && getSelectionCriteria().equals(query.getSelectionCriteria())));
307
            return false;
308
        }
309
        Expression selectionCriteria = getSelectionCriteria();
310
        Expression otherSelectionCriteria = query.getSelectionCriteria();
311
        return ((selectionCriteria == otherSelectionCriteria) || ((selectionCriteria != null) && selectionCriteria.equals(otherSelectionCriteria)));
307
    }
312
    }
308
        
313
        
309
    /**
314
    /**
Lines 311-326 Link Here
311
     * Compute a consistent hash-code for the expression.
316
     * Compute a consistent hash-code for the expression.
312
     * This is used to allow dynamic expression's SQL to be cached.
317
     * This is used to allow dynamic expression's SQL to be cached.
313
     */
318
     */
319
    @Override
314
    public int hashCode() {
320
    public int hashCode() {
315
        if (!isExpressionQuery()) {
321
        if (!isExpressionQuery()) {
316
            return super.hashCode();
322
            return super.hashCode();
317
        }
323
        }
318
        int hashCode = 32;
324
        int hashCode = 32;
319
        if (getReferenceClass() != null) {
325
        if (this.referenceClass != null) {
320
            hashCode = hashCode + getReferenceClass().hashCode();
326
            hashCode = hashCode + this.referenceClass.hashCode();
321
        }
327
        }
322
        if (getSelectionCriteria() != null) {
328
        Expression selectionCriteria = getSelectionCriteria();
323
            hashCode = hashCode + getSelectionCriteria().hashCode();
329
        if (selectionCriteria != null) {
330
            hashCode = hashCode + selectionCriteria.hashCode();
324
        }
331
        }
325
        return hashCode;
332
        return hashCode;
326
    }
333
    }
Lines 398-403 Link Here
398
     * INTERNAL:
405
     * INTERNAL:
399
     * Clone the query
406
     * Clone the query
400
     */
407
     */
408
    @Override
401
    public Object clone() {
409
    public Object clone() {
402
        ObjectLevelReadQuery cloneQuery = (ObjectLevelReadQuery)super.clone();
410
        ObjectLevelReadQuery cloneQuery = (ObjectLevelReadQuery)super.clone();
403
411
Lines 431-436 Link Here
431
     * Normally selection criteria are not cloned here as they are cloned
439
     * Normally selection criteria are not cloned here as they are cloned
432
     * later on during prepare.
440
     * later on during prepare.
433
     */
441
     */
442
    @Override
434
    public Object deepClone() {
443
    public Object deepClone() {
435
        ObjectLevelReadQuery clone = (ObjectLevelReadQuery)clone();
444
        ObjectLevelReadQuery clone = (ObjectLevelReadQuery)clone();
436
        if (getSelectionCriteria() != null) {
445
        if (getSelectionCriteria() != null) {
Lines 719-724 Link Here
719
     * INTERNAL:
728
     * INTERNAL:
720
     * Used to build the object, and register it if in the context of a unit of work. 
729
     * Used to build the object, and register it if in the context of a unit of work. 
721
     */
730
     */
731
    @Override
722
    public Object buildObject(AbstractRecord row) {
732
    public Object buildObject(AbstractRecord row) {
723
        return this.descriptor.getObjectBuilder().buildObject(this, row);
733
        return this.descriptor.getObjectBuilder().buildObject(this, row);
724
    }
734
    }
Lines 738-743 Link Here
738
     * INTERNAL:
748
     * INTERNAL:
739
     * Ensure that the descriptor has been set.
749
     * Ensure that the descriptor has been set.
740
     */
750
     */
751
    @Override
741
    public void checkDescriptor(AbstractSession session) throws QueryException {
752
    public void checkDescriptor(AbstractSession session) throws QueryException {
742
        if (this.descriptor == null) {
753
        if (this.descriptor == null) {
743
            if (getReferenceClass() == null) {
754
            if (getReferenceClass() == null) {
Lines 761-766 Link Here
761
     * INTERNAL:
772
     * INTERNAL:
762
     * Check to see if this query already knows the return value without performing any further work.
773
     * Check to see if this query already knows the return value without performing any further work.
763
     */
774
     */
775
    @Override
764
    public Object checkEarlyReturn(AbstractSession session, AbstractRecord translationRow) {
776
    public Object checkEarlyReturn(AbstractSession session, AbstractRecord translationRow) {
765
        // For bug 3136413/2610803 building the selection criteria from an EJBQL string or
777
        // For bug 3136413/2610803 building the selection criteria from an EJBQL string or
766
        // an example object is done just in time.
778
        // an example object is done just in time.
Lines 818-823 Link Here
818
     * Check to see if this query needs to be prepare and prepare it.
830
     * Check to see if this query needs to be prepare and prepare it.
819
     * The prepare is done on the original query to ensure that the work is not repeated.
831
     * The prepare is done on the original query to ensure that the work is not repeated.
820
     */
832
     */
833
    @Override
821
    public void checkPrepare(AbstractSession session, AbstractRecord translationRow, boolean force) {
834
    public void checkPrepare(AbstractSession session, AbstractRecord translationRow, boolean force) {
822
        // CR#3823735 For custom queries the prePrepare may not have been called yet.
835
        // CR#3823735 For custom queries the prePrepare may not have been called yet.
823
        if (!this.isPrePrepared || (this.descriptor == null)) {
836
        if (!this.isPrePrepared || (this.descriptor == null)) {
Lines 1033-1038 Link Here
1033
     * @exception  OptimisticLockException - an error has occurred using the optimistic lock feature.
1046
     * @exception  OptimisticLockException - an error has occurred using the optimistic lock feature.
1034
     * @return An object, the result of executing the query.
1047
     * @return An object, the result of executing the query.
1035
     */
1048
     */
1049
    @Override
1036
    public Object execute(AbstractSession session, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
1050
    public Object execute(AbstractSession session, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
1037
        //Bug#2839852  Refreshing is not possible if the query uses checkCacheOnly.
1051
        //Bug#2839852  Refreshing is not possible if the query uses checkCacheOnly.
1038
        if (shouldRefreshIdentityMapResult() && shouldCheckCacheOnly()) {
1052
        if (shouldRefreshIdentityMapResult() && shouldCheckCacheOnly()) {
Lines 1046-1051 Link Here
1046
     * INTERNAL:
1060
     * INTERNAL:
1047
     * Executes the prepared query on the datastore.
1061
     * Executes the prepared query on the datastore.
1048
     */
1062
     */
1063
    @Override
1049
    public Object executeDatabaseQuery() throws DatabaseException {
1064
    public Object executeDatabaseQuery() throws DatabaseException {
1050
        // PERF: If the query has been set to optimize building its result
1065
        // PERF: If the query has been set to optimize building its result
1051
        // directly from the database result-set then follow an optimized path.
1066
        // directly from the database result-set then follow an optimized path.
Lines 1119-1124 Link Here
1119
     * Execute the query in the unit of work.
1134
     * Execute the query in the unit of work.
1120
     * This allows any pre-execute checks to be done for unit of work queries.
1135
     * This allows any pre-execute checks to be done for unit of work queries.
1121
     */
1136
     */
1137
    @Override
1122
    public Object executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {        
1138
    public Object executeInUnitOfWork(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {        
1123
        Object result = null;
1139
        Object result = null;
1124
        
1140
        
Lines 1415-1424 Link Here
1415
    /**
1431
    /**
1416
     * INTERNAL:
1432
     * INTERNAL:
1417
     * Lookup the descriptor for this item by traversing its expression recursively.
1433
     * Lookup the descriptor for this item by traversing its expression recursively.
1418
     * @param expression
1419
     * @param rootDescriptor
1420
     * @return
1421
     * @throws org.eclipse.persistence.exceptions.QueryException
1422
     */
1434
     */
1423
    public ClassDescriptor getLeafDescriptorFor(Expression expression, ClassDescriptor rootDescriptor) throws QueryException {
1435
    public ClassDescriptor getLeafDescriptorFor(Expression expression, ClassDescriptor rootDescriptor) throws QueryException {
1424
        // The base case
1436
        // The base case
Lines 1522-1527 Link Here
1522
     * PUBLIC:
1534
     * PUBLIC:
1523
     * Return the reference class of the query.
1535
     * Return the reference class of the query.
1524
     */
1536
     */
1537
    @Override
1525
    public Class getReferenceClass() {
1538
    public Class getReferenceClass() {
1526
        return referenceClass;
1539
        return referenceClass;
1527
    }
1540
    }
Lines 1645-1650 Link Here
1645
    public Set<DatabaseField> getFetchGroupNonNestedFieldsSet() {
1658
    public Set<DatabaseField> getFetchGroupNonNestedFieldsSet() {
1646
        return getFetchGroupNonNestedFieldsSet(null);
1659
        return getFetchGroupNonNestedFieldsSet(null);
1647
    }
1660
    }
1661
    
1662
    /**
1663
     * INTERNAL:
1664
     * Return the set of fields required in the select clause, for fetch group reading.
1665
     */
1648
    public Set<DatabaseField> getFetchGroupNonNestedFieldsSet(DatabaseMapping nestedMapping) {
1666
    public Set<DatabaseField> getFetchGroupNonNestedFieldsSet(DatabaseMapping nestedMapping) {
1649
        Set fetchedFields = new HashSet(getExecutionFetchGroup().getAttributeNames().size());
1667
        Set fetchedFields = new HashSet(getExecutionFetchGroup().getAttributeNames().size());
1650
1668
Lines 1827-1832 Link Here
1827
     * PUBLIC:
1845
     * PUBLIC:
1828
     * Return if this is an object level read query.
1846
     * Return if this is an object level read query.
1829
     */
1847
     */
1848
    @Override
1830
    public boolean isObjectLevelReadQuery() {
1849
    public boolean isObjectLevelReadQuery() {
1831
        return true;
1850
        return true;
1832
    }
1851
    }
Lines 1906-1919 Link Here
1906
     */
1925
     */
1907
    public void setIsPrepared(boolean isPrepared) {
1926
    public void setIsPrepared(boolean isPrepared) {
1908
        super.setIsPrepared(isPrepared);
1927
        super.setIsPrepared(isPrepared);
1909
        this.isReferenceClassLocked = null;
1928
        if (!isPrepared) {
1910
        this.concreteSubclassCalls = null;
1929
            this.isReferenceClassLocked = null;
1930
            this.concreteSubclassCalls = null;
1931
        }
1911
    }
1932
    }
1912
1933
1913
    /**
1934
    /**
1914
     * INTERNAL:
1935
     * INTERNAL:
1915
     * Prepare the receiver for execution in a session.
1936
     * Prepare the receiver for execution in a session.
1916
     */
1937
     */
1938
    @Override
1917
    protected void prepare() throws QueryException {
1939
    protected void prepare() throws QueryException {
1918
        super.prepare();
1940
        super.prepare();
1919
        prepareQuery();
1941
        prepareQuery();
Lines 1955-1960 Link Here
1955
     * By default this calls prepareFromQuery, but additional properties may be required
1977
     * By default this calls prepareFromQuery, but additional properties may be required
1956
     * to be copied as prepareFromQuery only copies properties that affect the SQL.
1978
     * to be copied as prepareFromQuery only copies properties that affect the SQL.
1957
     */
1979
     */
1980
    @Override
1958
    public void copyFromQuery(DatabaseQuery query) {
1981
    public void copyFromQuery(DatabaseQuery query) {
1959
        super.copyFromQuery(query);
1982
        super.copyFromQuery(query);
1960
        if (query.isObjectLevelReadQuery()) {
1983
        if (query.isObjectLevelReadQuery()) {
Lines 1977-1982 Link Here
1977
     * dynamic queries.
2000
     * dynamic queries.
1978
     * This only copies over properties that are configured through EJBQL.
2001
     * This only copies over properties that are configured through EJBQL.
1979
     */
2002
     */
2003
    @Override
1980
    public void prepareFromQuery(DatabaseQuery query) {
2004
    public void prepareFromQuery(DatabaseQuery query) {
1981
        super.prepareFromQuery(query);
2005
        super.prepareFromQuery(query);
1982
        if (query.isObjectLevelReadQuery()) {
2006
        if (query.isObjectLevelReadQuery()) {
Lines 2181-2186 Link Here
2181
     * INTERNAL:
2205
     * INTERNAL:
2182
     * Prepare the receiver for execution in a session.
2206
     * Prepare the receiver for execution in a session.
2183
     */
2207
     */
2208
    @Override
2184
    protected void prepareForRemoteExecution() throws QueryException {
2209
    protected void prepareForRemoteExecution() throws QueryException {
2185
        super.prepareForRemoteExecution();
2210
        super.prepareForRemoteExecution();
2186
        checkPrePrepare(getSession());
2211
        checkPrePrepare(getSession());
Lines 2502-2507 Link Here
2502
     * REQUIRED:
2527
     * REQUIRED:
2503
     * Set the reference class for the query.
2528
     * Set the reference class for the query.
2504
     */
2529
     */
2530
    @Override
2505
    public void setReferenceClass(Class aClass) {
2531
    public void setReferenceClass(Class aClass) {
2506
        if (referenceClass != aClass) {
2532
        if (referenceClass != aClass) {
2507
            setIsPrepared(false);
2533
            setIsPrepared(false);
Lines 2513-2536 Link Here
2513
     * INTERNAL:
2539
     * INTERNAL:
2514
     * Set the reference class for the query.
2540
     * Set the reference class for the query.
2515
     */
2541
     */
2542
    @Override
2516
    public void setReferenceClassName(String aClass) {
2543
    public void setReferenceClassName(String aClass) {
2517
        if (referenceClassName != aClass) {
2544
        if (this.referenceClassName != aClass) {
2518
            setIsPrepared(false);
2545
            setIsPrepared(false);
2519
        }
2546
        }
2520
        referenceClassName = aClass;
2547
        this.referenceClassName = aClass;
2521
    }
2548
    }
2522
2549
2523
2550
2551
    /**
2552
     * PUBLIC:
2553
     * Set the Expression/where clause of the query.
2554
     * The expression should be defined using the query's ExpressionBuilder.
2555
     */
2556
    @Override
2524
    public void setSelectionCriteria(Expression expression) {
2557
    public void setSelectionCriteria(Expression expression) {
2525
        super.setSelectionCriteria(expression);
2558
        super.setSelectionCriteria(expression);
2526
        if ((expression != null) && (defaultBuilder != null) && (defaultBuilder.getQueryClass() == null)){
2559
        if ((expression != null) && (this.defaultBuilder != null) && (this.defaultBuilder.getQueryClass() == null)){
2527
            // For flashback: Must make sure expression and defaultBuilder always in sync.
2560
            // For flashback: Must make sure expression and defaultBuilder always in sync.
2528
            ExpressionBuilder newBuilder = expression.getBuilder();
2561
            ExpressionBuilder newBuilder = expression.getBuilder();
2529
            if (newBuilder != defaultBuilder) {
2562
            if (newBuilder != this.defaultBuilder) {
2530
                if (hasAsOfClause() && getAsOfClause().isUniversal()) {
2563
                if (hasAsOfClause() && getAsOfClause().isUniversal()) {
2531
                    newBuilder.asOf(defaultBuilder.getAsOfClause());
2564
                    newBuilder.asOf(this.defaultBuilder.getAsOfClause());
2532
                }
2565
                }
2533
                defaultBuilder = newBuilder;
2566
                this.defaultBuilder = newBuilder;
2534
            }
2567
            }
2535
        }
2568
        }
2536
    }
2569
    }
Lines 2711-2716 Link Here
2711
     * i.e. does not use any properties that may conflict with another query
2744
     * i.e. does not use any properties that may conflict with another query
2712
     * with the same JPQL or selection criteria.
2745
     * with the same JPQL or selection criteria.
2713
     */
2746
     */
2747
    @Override
2714
    public boolean isDefaultPropertiesQuery() {
2748
    public boolean isDefaultPropertiesQuery() {
2715
        return super.isDefaultPropertiesQuery()
2749
        return super.isDefaultPropertiesQuery()
2716
            && (!this.isResultSetOptimizedQuery)
2750
            && (!this.isResultSetOptimizedQuery)
Lines 3111-3116 Link Here
3111
        getBatchFetchPolicy().setBatchObjects(batchObjects);
3145
        getBatchFetchPolicy().setBatchObjects(batchObjects);
3112
    }
3146
    }
3113
3147
3148
    @Override
3114
    public String toString() {
3149
    public String toString() {
3115
        String str = super.toString();
3150
        String str = super.toString();
3116
        if(this.fetchGroup != null) {
3151
        if(this.fetchGroup != null) {
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ReadAllQuery.java (-2 / +20 lines)
Lines 148-153 Link Here
148
     * It will cause the original to be cached in the query results if the query
148
     * It will cause the original to be cached in the query results if the query
149
     * is set to do so.
149
     * is set to do so.
150
     */
150
     */
151
    @Override
151
    public void cacheResult(Object unwrappedOriginal) {
152
    public void cacheResult(Object unwrappedOriginal) {
152
        Collection container = (Collection)getTemporaryCachedQueryResults();
153
        Collection container = (Collection)getTemporaryCachedQueryResults();
153
        if (container == null) {
154
        if (container == null) {
Lines 161-166 Link Here
161
     * INTERNAL:
162
     * INTERNAL:
162
     * The cache check is done before the prepare as a hit will not require the work to be done.
163
     * The cache check is done before the prepare as a hit will not require the work to be done.
163
     */
164
     */
165
    @Override
164
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
166
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
165
        // Check for in-memory only query.
167
        // Check for in-memory only query.
166
        if (shouldCheckCacheOnly()) {
168
        if (shouldCheckCacheOnly()) {
Lines 196-201 Link Here
196
     * This is done before the query is copied and prepared/executed.
198
     * This is done before the query is copied and prepared/executed.
197
     * null means there is none.
199
     * null means there is none.
198
     */
200
     */
201
    @Override
199
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
202
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
200
        checkDescriptor(session);
203
        checkDescriptor(session);
201
204
Lines 214-219 Link Here
214
     * INTERNAL:
217
     * INTERNAL:
215
     * Clone the query.
218
     * Clone the query.
216
     */
219
     */
220
    @Override
217
    public Object clone() {
221
    public Object clone() {
218
        ReadAllQuery cloneQuery = (ReadAllQuery)super.clone();
222
        ReadAllQuery cloneQuery = (ReadAllQuery)super.clone();
219
223
Lines 343-348 Link Here
343
     * @return An object or vector, the result of executing the query.
347
     * @return An object or vector, the result of executing the query.
344
     * @exception DatabaseException - an error has occurred on the database
348
     * @exception DatabaseException - an error has occurred on the database
345
     */
349
     */
350
    @Override
346
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {        
351
    public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {        
347
        if (shouldCacheQueryResults()) {
352
        if (shouldCacheQueryResults()) {
348
            if (getContainerPolicy().overridesRead()) {
353
            if (getContainerPolicy().overridesRead()) {
Lines 392-397 Link Here
392
     * @exception  DatabaseException - an error has occurred on the database
397
     * @exception  DatabaseException - an error has occurred on the database
393
     * @return java.lang.Object collection of objects resulting from execution of query.
398
     * @return java.lang.Object collection of objects resulting from execution of query.
394
     */
399
     */
400
    @Override
395
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
401
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
396
        Object result = null;
402
        Object result = null;
397
        
403
        
Lines 456-461 Link Here
456
     * @exception  DatabaseException - an error has occurred on the database
462
     * @exception  DatabaseException - an error has occurred on the database
457
     * @return an ArrayList of the resulting objects.
463
     * @return an ArrayList of the resulting objects.
458
     */
464
     */
465
    @Override
459
    protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException {
466
    protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException {
460
        AbstractSession session = this.session;
467
        AbstractSession session = this.session;
461
        DatabasePlatform platform = session.getPlatform();
468
        DatabasePlatform platform = session.getPlatform();
Lines 511-516 Link Here
511
     * INTERNAL:
518
     * INTERNAL:
512
     * Extract the correct query result from the transporter.
519
     * Extract the correct query result from the transporter.
513
     */
520
     */
521
    @Override
514
    public Object extractRemoteResult(Transporter transporter) {
522
    public Object extractRemoteResult(Transporter transporter) {
515
        return ((RemoteSession)getSession()).getObjectsCorrespondingToAll(transporter.getObject(), transporter.getObjectDescriptors(), new IdentityHashMap(), this, getContainerPolicy());
523
        return ((RemoteSession)getSession()).getObjectsCorrespondingToAll(transporter.getObject(), transporter.getObjectDescriptors(), new IdentityHashMap(), this, getContainerPolicy());
516
    }
524
    }
Lines 518-524 Link Here
518
    /**
526
    /**
519
     * INTERNAL:
527
     * INTERNAL:
520
     * Return the query's container policy.
528
     * Return the query's container policy.
521
     * @return org.eclipse.persistence.internal.queries.ContainerPolicy
522
     */
529
     */
523
    public ContainerPolicy getContainerPolicy() {
530
    public ContainerPolicy getContainerPolicy() {
524
        return containerPolicy;
531
        return containerPolicy;
Lines 529-535 Link Here
529
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
536
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
530
     * See ClassDescriptor for their types.
537
     * See ClassDescriptor for their types.
531
     */
538
     */
532
    protected QueryRedirector getDefaultRedirector(){
539
    @Override
540
    protected QueryRedirector getDefaultRedirector() {
533
        return descriptor.getDefaultReadAllQueryRedirector();
541
        return descriptor.getDefaultReadAllQueryRedirector();
534
    }
542
    }
535
543
Lines 573-578 Link Here
573
     * i.e. does not use any properties that may conflict with another query
581
     * i.e. does not use any properties that may conflict with another query
574
     * with the same JPQL or selection criteria.
582
     * with the same JPQL or selection criteria.
575
     */
583
     */
584
    @Override
576
    public boolean isDefaultPropertiesQuery() {
585
    public boolean isDefaultPropertiesQuery() {
577
        return super.isDefaultPropertiesQuery()
586
        return super.isDefaultPropertiesQuery()
578
            && (!hasBatchReadAttributes())
587
            && (!hasBatchReadAttributes())
Lines 585-590 Link Here
585
     * Return if the query is equal to the other.
594
     * Return if the query is equal to the other.
586
     * This is used to allow dynamic expression query SQL to be cached.
595
     * This is used to allow dynamic expression query SQL to be cached.
587
     */
596
     */
597
    @Override
588
    public boolean equals(Object object) {
598
    public boolean equals(Object object) {
589
        if (this == object) {
599
        if (this == object) {
590
            return true;
600
            return true;
Lines 603-608 Link Here
603
     * PUBLIC:
613
     * PUBLIC:
604
     * Return if this is a read all query.
614
     * Return if this is a read all query.
605
     */
615
     */
616
    @Override
606
    public boolean isReadAllQuery() {
617
    public boolean isReadAllQuery() {
607
        return true;
618
        return true;
608
    }
619
    }
Lines 611-616 Link Here
611
     * INTERNAL:
622
     * INTERNAL:
612
     * Prepare the receiver for execution in a session.
623
     * Prepare the receiver for execution in a session.
613
     */
624
     */
625
    @Override
614
    protected void prepare() throws QueryException {
626
    protected void prepare() throws QueryException {
615
        if ((!isReportQuery()) && prepareFromCachedQuery()) {
627
        if ((!isReportQuery()) && prepareFromCachedQuery()) {
616
            return;
628
            return;
Lines 638-643 Link Here
638
     * dynamic queries.
650
     * dynamic queries.
639
     * This only copies over properties that are configured through JPQL.
651
     * This only copies over properties that are configured through JPQL.
640
     */
652
     */
653
    @Override
641
    public void prepareFromQuery(DatabaseQuery query) {
654
    public void prepareFromQuery(DatabaseQuery query) {
642
        super.prepareFromQuery(query);
655
        super.prepareFromQuery(query);
643
        if (query.isReadAllQuery()) {
656
        if (query.isReadAllQuery()) {
Lines 655-660 Link Here
655
     * INTERNAL:
668
     * INTERNAL:
656
     * Set the properties needed to be cascaded into the custom query.
669
     * Set the properties needed to be cascaded into the custom query.
657
     */
670
     */
671
    @Override
658
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
672
    protected void prepareCustomQuery(DatabaseQuery customQuery) {
659
        ReadAllQuery customReadQuery = (ReadAllQuery)customQuery;
673
        ReadAllQuery customReadQuery = (ReadAllQuery)customQuery;
660
        customReadQuery.containerPolicy = this.containerPolicy;
674
        customReadQuery.containerPolicy = this.containerPolicy;
Lines 668-673 Link Here
668
     * INTERNAL:
682
     * INTERNAL:
669
     * Prepare the receiver for execution in a session.
683
     * Prepare the receiver for execution in a session.
670
     */
684
     */
685
    @Override
671
    public void prepareForExecution() throws QueryException {
686
    public void prepareForExecution() throws QueryException {
672
        super.prepareForExecution();
687
        super.prepareForExecution();
673
        
688
        
Lines 710-715 Link Here
710
     *
725
     *
711
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
726
     * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
712
     */
727
     */
728
    @Override
713
    public Object registerResultInUnitOfWork(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
729
    public Object registerResultInUnitOfWork(Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) {
714
        // For bug 2612366: Conforming results in UOW extremely slow.
730
        // For bug 2612366: Conforming results in UOW extremely slow.
715
        // Replacing results with registered versions in the UOW is a part of 
731
        // Replacing results with registered versions in the UOW is a part of 
Lines 795-800 Link Here
795
     * INTERNAL:
811
     * INTERNAL:
796
     * Execute the query through remote session.
812
     * Execute the query through remote session.
797
     */
813
     */
814
    @Override
798
    public Object remoteExecute() {
815
    public Object remoteExecute() {
799
        if (this.containerPolicy.overridesRead()) {
816
        if (this.containerPolicy.overridesRead()) {
800
            return this.containerPolicy.remoteExecute();
817
            return this.containerPolicy.remoteExecute();
Lines 812-817 Link Here
812
     * INTERNAL:
829
     * INTERNAL:
813
     * replace the value holders in the specified result object(s)
830
     * replace the value holders in the specified result object(s)
814
     */
831
     */
832
    @Override
815
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
833
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
816
        return controller.replaceValueHoldersInAll(object, getContainerPolicy());
834
        return controller.replaceValueHoldersInAll(object, getContainerPolicy());
817
    }
835
    }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ReportQuery.java (-22 / +13 lines)
Lines 582-587 Link Here
582
     * By default return the row.
582
     * By default return the row.
583
     * Used by cursored stream.
583
     * Used by cursored stream.
584
     */
584
     */
585
    @Override
585
    public Object buildObject(AbstractRecord row) {
586
    public Object buildObject(AbstractRecord row) {
586
        return buildObject(row, null);
587
        return buildObject(row, null);
587
    }
588
    }
Lines 658-663 Link Here
658
     * INTERNAL:
659
     * INTERNAL:
659
     * The cache check is done before the prepare as a hit will not require the work to be done.
660
     * The cache check is done before the prepare as a hit will not require the work to be done.
660
     */
661
     */
662
    @Override
661
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
663
    protected Object checkEarlyReturnLocal(AbstractSession session, AbstractRecord translationRow) {
662
        // Check for in-memory only query.
664
        // Check for in-memory only query.
663
        if (shouldCheckCacheOnly()) {
665
        if (shouldCheckCacheOnly()) {
Lines 673-678 Link Here
673
     * This is done before the query is copied and prepared/executed.
675
     * This is done before the query is copied and prepared/executed.
674
     * null means there is none.
676
     * null means there is none.
675
     */
677
     */
678
    @Override
676
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
679
    protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
677
        return null;
680
        return null;
678
    }
681
    }
Lines 681-686 Link Here
681
     * INTERNAL:
684
     * INTERNAL:
682
     * Clone the query.
685
     * Clone the query.
683
     */
686
     */
687
    @Override
684
    public Object clone() {
688
    public Object clone() {
685
        ReportQuery cloneQuery = (ReportQuery)super.clone();
689
        ReportQuery cloneQuery = (ReportQuery)super.clone();
686
        cloneQuery.items = new ArrayList<ReportItem>(this.items.size());
690
        cloneQuery.items = new ArrayList<ReportItem>(this.items.size());
Lines 813-818 Link Here
813
     * @exception  DatabaseException - an error has occurred on the database
817
     * @exception  DatabaseException - an error has occurred on the database
814
     * @return either collection of objects, or report data resulting from execution of query.
818
     * @return either collection of objects, or report data resulting from execution of query.
815
     */
819
     */
820
    @Override
816
    public Object executeDatabaseQuery() throws DatabaseException {
821
    public Object executeDatabaseQuery() throws DatabaseException {
817
        // ensure a pessimistic locking query will go down the write connection
822
        // ensure a pessimistic locking query will go down the write connection
818
       if (isLockQuery() && getSession().isUnitOfWork()) {
823
       if (isLockQuery() && getSession().isUnitOfWork()) {
Lines 845-850 Link Here
845
     * INTERNAL:
850
     * INTERNAL:
846
     * Extract the correct query result from the transporter.
851
     * Extract the correct query result from the transporter.
847
     */
852
     */
853
    @Override
848
    public Object extractRemoteResult(Transporter transporter) {
854
    public Object extractRemoteResult(Transporter transporter) {
849
        return transporter.getObject();
855
        return transporter.getObject();
850
    }
856
    }
Lines 916-921 Link Here
916
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
922
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
917
     * See ClassDescriptor for their types.
923
     * See ClassDescriptor for their types.
918
     */
924
     */
925
    @Override
919
    protected QueryRedirector getDefaultRedirector(){
926
    protected QueryRedirector getDefaultRedirector(){
920
        return descriptor.getDefaultReportQueryRedirector();
927
        return descriptor.getDefaultReportQueryRedirector();
921
    }
928
    }
Lines 1014-1019 Link Here
1014
     * PUBLIC:
1021
     * PUBLIC:
1015
     * Return if this is a report query.
1022
     * Return if this is a report query.
1016
     */
1023
     */
1024
    @Override
1017
    public boolean isReportQuery() {
1025
    public boolean isReportQuery() {
1018
        return true;
1026
        return true;
1019
    }
1027
    }
Lines 1023-1028 Link Here
1023
     * Prepare the receiver for execution in a session.
1031
     * Prepare the receiver for execution in a session.
1024
     * Initialize each item with its DTF mapping
1032
     * Initialize each item with its DTF mapping
1025
     */
1033
     */
1034
    @Override
1026
    protected void prepare() throws QueryException {
1035
    protected void prepare() throws QueryException {
1027
        if (prepareFromCachedQuery()) {
1036
        if (prepareFromCachedQuery()) {
1028
            return;
1037
            return;
Lines 1067-1072 Link Here
1067
     * dynamic queries.
1076
     * dynamic queries.
1068
     * This only copies over properties that are configured through EJBQL.
1077
     * This only copies over properties that are configured through EJBQL.
1069
     */
1078
     */
1079
    @Override
1070
    public void prepareFromQuery(DatabaseQuery query) {
1080
    public void prepareFromQuery(DatabaseQuery query) {
1071
        super.prepareFromQuery(query);
1081
        super.prepareFromQuery(query);
1072
        if (query.isReportQuery()) {
1082
        if (query.isReportQuery()) {
Lines 1080-1105 Link Here
1080
            this.shouldRetrievePrimaryKeys = reportQuery.shouldRetrievePrimaryKeys;
1090
            this.shouldRetrievePrimaryKeys = reportQuery.shouldRetrievePrimaryKeys;
1081
        }
1091
        }
1082
    }
1092
    }
1083
        
1084
    /**
1085
     * INTERNAL:
1086
     * Return true if the query uses default properties.
1087
     * This is used to determine if this query is cacheable.
1088
     * i.e. does not use any properties that may conflict with another query
1089
     * with the same EJBQL or selection criteria.
1090
     */
1091
    public boolean isDefaultPropertiesQuery() {
1092
        return super.isDefaultPropertiesQuery()
1093
            && (!hasBatchReadAttributes())
1094
            && (!hasHierarchicalExpressions())
1095
            && (!getContainerPolicy().isCursorPolicy());
1096
    }
1097
    
1093
    
1098
    /**
1094
    /**
1099
     * INTERNAL:
1095
     * INTERNAL:
1100
     * Return if the query is equal to the other.
1096
     * Return if the query is equal to the other.
1101
     * This is used to allow dynamic expression query SQL to be cached.
1097
     * This is used to allow dynamic expression query SQL to be cached.
1102
     */
1098
     */
1099
    @Override
1103
    public boolean equals(Object object) {
1100
    public boolean equals(Object object) {
1104
        if (this == object) {
1101
        if (this == object) {
1105
            return true;
1102
            return true;
Lines 1292-1297 Link Here
1292
     * INTERNAL:
1289
     * INTERNAL:
1293
     * Prepare the mechanism.
1290
     * Prepare the mechanism.
1294
     */
1291
     */
1292
    @Override
1295
    protected void prepareSelectAllRows() {
1293
    protected void prepareSelectAllRows() {
1296
        prepareObjectAttributeCount(null);
1294
        prepareObjectAttributeCount(null);
1297
1295
Lines 1335-1353 Link Here
1335
        setSession(null);
1333
        setSession(null);
1336
        setTranslationRow(null);
1334
        setTranslationRow(null);
1337
    }
1335
    }
1338
1339
    /**
1340
     * INTERNAL:
1341
     * Avoid processing fetch-groups for report query.
1342
     */
1343
    public void initializeFetchGroup() {
1344
        // Do nothing.
1345
    }
1346
    
1336
    
1347
    /**
1337
    /**
1348
     * INTERNAL:
1338
     * INTERNAL:
1349
     * replace the value holders in the specified result object(s)
1339
     * replace the value holders in the specified result object(s)
1350
     */
1340
     */
1341
    @Override
1351
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
1342
    public Map replaceValueHoldersIn(Object object, RemoteSessionController controller) {
1352
        // do nothing, since report queries do not return domain objects
1343
        // do nothing, since report queries do not return domain objects
1353
        return null;
1344
        return null;
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ResultSetMappingQuery.java (-25 / +6 lines)
Lines 72-77 Link Here
72
     * It will cause the original to be cached in the query results if the query
72
     * It will cause the original to be cached in the query results if the query
73
     * is set to do so.
73
     * is set to do so.
74
     */
74
     */
75
    @Override
75
    public void cacheResult(Object unwrappedOriginal) {
76
    public void cacheResult(Object unwrappedOriginal) {
76
        Object cachableObject = unwrappedOriginal;
77
        Object cachableObject = unwrappedOriginal;
77
        if (shouldUseWrapperPolicy()){
78
        if (shouldUseWrapperPolicy()){
Lines 80-120 Link Here
80
        setTemporaryCachedQueryResults(cachableObject);
81
        setTemporaryCachedQueryResults(cachableObject);
81
    }
82
    }
82
83
83
/**
84
     * INTERNAL:
85
     * Clone the query.
86
     */
87
    public Object clone() {
88
        ResultSetMappingQuery cloneQuery = (ResultSetMappingQuery)super.clone();
89
        cloneQuery.resultSetMapping = this.resultSetMapping;
90
        cloneQuery.resultSetMappingName = this.resultSetMappingName;
91
        return cloneQuery;
92
    }
93
94
    /**
84
    /**
95
     * INTERNAL:
85
     * INTERNAL:
96
     * Convert all the class-name-based settings in this ResultSetMapping to actual class-based
86
     * Convert all the class-name-based settings in this ResultSetMapping to actual class-based
97
     * settings. This method is used when converting a project that has been built
87
     * settings. This method is used when converting a project that has been built
98
     * with class names to a project with classes.
88
     * with class names to a project with classes.
99
     * @param classLoader 
100
     */
89
     */
90
    @Override
101
    public void convertClassNamesToClasses(ClassLoader classLoader){
91
    public void convertClassNamesToClasses(ClassLoader classLoader){
102
        resultSetMapping.convertClassNamesToClasses(classLoader);
92
        this.resultSetMapping.convertClassNamesToClasses(classLoader);
103
    };  
93
    }
104
94
105
    /**
95
    /**
106
     * PUBLIC:
96
     * PUBLIC:
107
     * Used to define a store procedure or SQL query.
108
     */
109
/*    public void setCall(Call call) {
110
        if (call instanceof SQLCall){
111
            ((SQLCall)call).setSQLString(((SQLCall)call).getCallString().replace('?','#'));
112
        }
113
        super.setCall(call);
114
    }
115
*/
116
    /**
117
     * PUBLIC:
118
     * This will be the SQLResultSetMapping that is used by this query to process
97
     * This will be the SQLResultSetMapping that is used by this query to process
119
     * the database results
98
     * the database results
120
     */
99
     */
Lines 177-182 Link Here
177
     * INTERNAL:
156
     * INTERNAL:
178
     * Executes the prepared query on the datastore.
157
     * Executes the prepared query on the datastore.
179
     */
158
     */
159
    @Override
180
    public Object executeDatabaseQuery() throws DatabaseException {
160
    public Object executeDatabaseQuery() throws DatabaseException {
181
        if (getSession().isUnitOfWork()) {
161
        if (getSession().isUnitOfWork()) {
182
            UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)getSession();
162
            UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)getSession();
Lines 219-224 Link Here
219
     * INTERNAL:
199
     * INTERNAL:
220
     * Prepare the receiver for execution in a session.
200
     * Prepare the receiver for execution in a session.
221
     */
201
     */
202
    @Override
222
    protected void prepare() {
203
    protected void prepare() {
223
        if ((!shouldMaintainCache()) && shouldRefreshIdentityMapResult()) {
204
        if ((!shouldMaintainCache()) && shouldRefreshIdentityMapResult()) {
224
            throw QueryException.refreshNotPossibleWithoutCache(this);
205
            throw QueryException.refreshNotPossibleWithoutCache(this);
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/SQLCall.java (-18 / +23 lines)
Lines 13-19 Link Here
13
 ******************************************************************************/  
13
 ******************************************************************************/  
14
package org.eclipse.persistence.queries;
14
package org.eclipse.persistence.queries;
15
15
16
import java.util.Vector;
16
import java.util.List;
17
import java.io.*;
17
import java.io.*;
18
import org.eclipse.persistence.internal.databaseaccess.*;
18
import org.eclipse.persistence.internal.databaseaccess.*;
19
import org.eclipse.persistence.internal.helper.DatabaseField;
19
import org.eclipse.persistence.internal.helper.DatabaseField;
Lines 56-88 Link Here
56
     * INTERNAL:
56
     * INTERNAL:
57
     * Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
57
     * Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
58
     */
58
     */
59
    protected void afterTranslateCustomQuery(Vector updatedParameters, Vector updatedParameterTypes) {
59
    protected void afterTranslateCustomQuery(List updatedParameters, List<Integer> updatedParameterTypes) {
60
        for (int i = 0; i < getParameters().size(); i++) {
60
        int size = getParameters().size();
61
            Integer parameterType = (Integer)getParameterTypes().elementAt(i);
61
        for (int i = 0; i < size; i++) {
62
            Object parameter = getParameters().elementAt(i);
62
            Integer parameterType = this.parameterTypes.get(i);
63
            Object parameter = this.parameters.get(i);
63
            if ((parameterType == MODIFY) || (parameterType == OUT) || (parameterType == OUT_CURSOR) || ((parameterType == IN) && parameter instanceof DatabaseField)) {
64
            if ((parameterType == MODIFY) || (parameterType == OUT) || (parameterType == OUT_CURSOR) || ((parameterType == IN) && parameter instanceof DatabaseField)) {
64
                DatabaseField field = afterTranslateCustomQueryUpdateParameter((DatabaseField)parameter, i, parameterType, updatedParameters, updatedParameterTypes);
65
                DatabaseField field = afterTranslateCustomQueryUpdateParameter((DatabaseField)parameter, i, parameterType, updatedParameters, updatedParameterTypes);
65
                if (field!=null){
66
                if (field!=null){
66
                    getParameters().setElementAt(field, i);
67
                    this.parameters.set(i, field);
67
                }
68
                }
68
            } else if (parameterType == INOUT) {
69
            } else if (parameterType == INOUT) {
69
                DatabaseField outField = afterTranslateCustomQueryUpdateParameter((DatabaseField)((Object[])parameter)[1], i, parameterType, updatedParameters, updatedParameterTypes);
70
                DatabaseField outField = afterTranslateCustomQueryUpdateParameter((DatabaseField)((Object[])parameter)[1], i, parameterType, updatedParameters, updatedParameterTypes);
70
                if (outField !=null){
71
                if (outField != null) {
71
                    if (((Object[])parameter)[0] instanceof DatabaseField){
72
                    if (((Object[])parameter)[0] instanceof DatabaseField){
72
                        if ( ((Object[])parameter)[0] != ((Object[])parameter)[1] ) {
73
                        if ( ((Object[])parameter)[0] != ((Object[])parameter)[1] ) {
73
                            DatabaseField inField = outField.clone();
74
                            DatabaseField inField = outField.clone();
74
                            inField.setName( ((DatabaseField)((Object[])parameter)[0]).getName());
75
                            inField.setName( ((DatabaseField)((Object[])parameter)[0]).getName());
75
                            ((Object[])parameter)[0] = inField;
76
                            ((Object[])parameter)[0] = inField;
76
                        }else {
77
                        } else {
77
                            ((Object[])parameter)[0] = outField;
78
                            ((Object[])parameter)[0] = outField;
78
                        }
79
                        }
79
                    }
80
                    }
80
                    ((Object[])parameter)[1] = outField;
81
                    ((Object[])parameter)[1] = outField;
81
                }
82
                }
82
            } else if ((parameterType == IN)&& (parameter instanceof DatabaseField)){
83
            } else if ((parameterType == IN) && (parameter instanceof DatabaseField)){
83
                DatabaseField field = afterTranslateCustomQueryUpdateParameter((DatabaseField)parameter, i, parameterType, updatedParameters, updatedParameterTypes);
84
                DatabaseField field = afterTranslateCustomQueryUpdateParameter((DatabaseField)parameter, i, parameterType, updatedParameters, updatedParameterTypes);
84
                if (field!=null){
85
                if (field != null) {
85
                    getParameters().setElementAt(field, i);
86
                    this.parameters.set(i, field);
86
                }
87
                }
87
            }
88
            }
88
        }
89
        }
Lines 93-108 Link Here
93
     * Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
94
     * Set the data passed through setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods.
94
     * This will return the null if the user did not add the field/type using the setCustomSQLArgumentType method
95
     * This will return the null if the user did not add the field/type using the setCustomSQLArgumentType method
95
     */
96
     */
96
    protected DatabaseField afterTranslateCustomQueryUpdateParameter(DatabaseField field, int index, Integer parameterType, Vector updatedParameters, Vector updatedParameterTypes) {
97
    protected DatabaseField afterTranslateCustomQueryUpdateParameter(DatabaseField field, int index, Integer parameterType, List updatedParameters, List<Integer> updatedParameterTypes) {
97
        for (int j = 0; j < updatedParameters.size(); j++) {
98
        int size = updatedParameters.size();
98
            DatabaseField updateField = (DatabaseField)updatedParameters.elementAt(j);
99
        for (int j = 0; j < size; j++) {
100
            DatabaseField updateField = (DatabaseField)updatedParameters.get(j);
99
            if (field.equals(updateField)) {
101
            if (field.equals(updateField)) {
100
                Integer updateParameterType = (Integer)updatedParameterTypes.elementAt(j);
102
                Integer updateParameterType = updatedParameterTypes.get(j);
101
                if (updateParameterType == null) {
103
                if (updateParameterType == null) {
102
                    return updateField;
104
                    return updateField;
103
                } else if (updateParameterType == OUT_CURSOR) {
105
                } else if (updateParameterType == OUT_CURSOR) {
104
                    if (parameterType == OUT) {
106
                    if (parameterType == OUT) {
105
                        getParameterTypes().setElementAt(OUT_CURSOR, index);
107
                        this.parameterTypes.set(index, OUT_CURSOR);
106
                        return updateField;
108
                        return updateField;
107
                    } else {
109
                    } else {
108
                        throw ValidationException.cannotSetCursorForParameterTypeOtherThanOut(field.getName(), toString());
110
                        throw ValidationException.cannotSetCursorForParameterTypeOtherThanOut(field.getName(), toString());
Lines 122-131 Link Here
122
        return hasCustomSQLArguments;
124
        return hasCustomSQLArguments;
123
    }
125
    }
124
126
127
    @Override
125
    public boolean isSQLCall() {
128
    public boolean isSQLCall() {
126
        return true;
129
        return true;
127
    }
130
    }
128
131
132
    @Override
129
    public boolean isQueryStringCall() {
133
    public boolean isQueryStringCall() {
130
        return true;
134
        return true;
131
    }
135
    }
Lines 134-144 Link Here
134
     * INTERNAL:
138
     * INTERNAL:
135
     * Called by prepare method only.
139
     * Called by prepare method only.
136
     */
140
     */
141
    @Override
137
    protected void prepareInternal(AbstractSession session) {
142
    protected void prepareInternal(AbstractSession session) {
138
        if (hasCustomSQLArguments()) {
143
        if (hasCustomSQLArguments()) {
139
            // hold results of setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods
144
            // hold results of setCustomSQLArgumentType and useCustomSQLCursorOutputAsResultSet methods
140
            Vector updatedParameters = null;
145
            List updatedParameters = null;
141
            Vector updatedParameterTypes = null;
146
            List updatedParameterTypes = null;
142
            if (getParameters().size() > 0) {
147
            if (getParameters().size() > 0) {
143
                updatedParameters = getParameters();
148
                updatedParameters = getParameters();
144
                setParameters(org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance());
149
                setParameters(org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance());
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/StoredFunctionCall.java (-2 / +25 lines)
Lines 94-100 Link Here
94
     * Define the field name to be substitute for the function return.
94
     * Define the field name to be substitute for the function return.
95
     */
95
     */
96
    public void setResult(String name) {
96
    public void setResult(String name) {
97
        DatabaseField returnField = (DatabaseField)getParameters().firstElement();
97
        DatabaseField returnField = (DatabaseField)getParameters().get(0);
98
        returnField.setName(name);
98
        returnField.setName(name);
99
    }
99
    }
100
100
Lines 104-111 Link Here
104
     * The type is the type of Java class desired back from the function, this is dependent on the type returned from the function.
104
     * The type is the type of Java class desired back from the function, this is dependent on the type returned from the function.
105
     */
105
     */
106
    public void setResult(String name, Class type) {
106
    public void setResult(String name, Class type) {
107
        DatabaseField returnField = (DatabaseField)getParameters().firstElement();
107
        DatabaseField returnField = (DatabaseField)getParameters().get(0);
108
        returnField.setName(name);
108
        returnField.setName(name);
109
        returnField.setType(type);
109
        returnField.setType(type);
110
    }
110
    }
111
112
    /**
113
     * PUBLIC:
114
     * Define the field name to be substitute for the function return.
115
     * The type is the type of Java class desired back from the function, this is dependent on the type returned from the function.
116
     */
117
    public void setResult(String name, int type, String typeName) {
118
        ObjectRelationalDatabaseField field = new ObjectRelationalDatabaseField(name);
119
        field.setSqlType(type);
120
        field.setSqlTypeName(typeName);
121
        getParameters().set(0, field);
122
    }
123
124
    /**
125
     * PUBLIC:
126
     * Define the field name to be substitute for the function return.
127
     * The type is the type of Java class desired back from the function, this is dependent on the type returned from the function.
128
     */
129
    public void setResult(String name, int type) {
130
        DatabaseField returnField = (DatabaseField)getParameters().get(0);
131
        returnField.setName(name);
132
        returnField.setSqlType(type);
133
    }
111
}
134
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/StoredProcedureCall.java (-10 / +49 lines)
Lines 12-21 Link Here
12
 ******************************************************************************/  
12
 ******************************************************************************/  
13
package org.eclipse.persistence.queries;
13
package org.eclipse.persistence.queries;
14
14
15
//javase imports
15
import java.util.ArrayList;
16
import java.util.Vector;
16
import java.util.List;
17
17
18
//EclipseLink imports
19
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
18
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
20
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
19
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
21
import org.eclipse.persistence.internal.helper.DatabaseField;
20
import org.eclipse.persistence.internal.helper.DatabaseField;
Lines 30-36 Link Here
30
 */
29
 */
31
public class StoredProcedureCall extends DatabaseCall {
30
public class StoredProcedureCall extends DatabaseCall {
32
    protected String procedureName;
31
    protected String procedureName;
33
    protected Vector procedureArgumentNames;
32
    protected List<String> procedureArgumentNames;
33
    protected List<DatabaseField> optionalArguments;
34
34
35
    public StoredProcedureCall() {
35
    public StoredProcedureCall() {
36
        super();
36
        super();
Lines 769-777 Link Here
769
     * The if the names are provide the order is not required to match the call def.
769
     * The if the names are provide the order is not required to match the call def.
770
     * This is lazy initialized to conserve space on calls that have no parameters.
770
     * This is lazy initialized to conserve space on calls that have no parameters.
771
     */
771
     */
772
    public Vector getProcedureArgumentNames() {
772
    public List<String> getProcedureArgumentNames() {
773
        if (procedureArgumentNames == null) {
773
        if (procedureArgumentNames == null) {
774
            procedureArgumentNames = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
774
            procedureArgumentNames = new ArrayList<String>();
775
        }
775
        }
776
        return procedureArgumentNames;
776
        return procedureArgumentNames;
777
    }
777
    }
Lines 792-799 Link Here
792
     * INTERNAL:
792
     * INTERNAL:
793
     * Called by prepare method only.
793
     * Called by prepare method only.
794
     */
794
     */
795
    protected void prepareInternal(AbstractSession session) {
795
    @Override
796
        setSQLStringInternal(session.getPlatform().buildProcedureCallString(this, session));
796
    protected void prepareInternal(AbstractSession session) {        
797
        setSQLStringInternal(session.getPlatform().buildProcedureCallString(this, session, getQuery().getTranslationRow()));
797
        super.prepareInternal(session);
798
        super.prepareInternal(session);
798
    }
799
    }
799
800
Lines 802-808 Link Here
802
     * The if the names are provide the order is not required to match the call def.
803
     * The if the names are provide the order is not required to match the call def.
803
     * This is lazy initialized to conserve space on calls that have no parameters.
804
     * This is lazy initialized to conserve space on calls that have no parameters.
804
     */
805
     */
805
    public void setProcedureArgumentNames(Vector procedureArgumentNames) {
806
    public void setProcedureArgumentNames(List<String> procedureArgumentNames) {
806
        this.procedureArgumentNames = procedureArgumentNames;
807
        this.procedureArgumentNames = procedureArgumentNames;
807
    }
808
    }
808
809
Lines 884-889 Link Here
884
     * For Oracle a cursored output parameter can be used instead of a result set.
885
     * For Oracle a cursored output parameter can be used instead of a result set.
885
     */
886
     */
886
    public void setReturnsResultSet(boolean returnsResultSet) {
887
    public void setReturnsResultSet(boolean returnsResultSet) {
887
        this.returnsResultSet = Boolean.valueOf(returnsResultSet);
888
        super.setReturnsResultSet(returnsResultSet);
888
    }
889
    }
890
891
    /**
892
     * PUBLIC:
893
     * Add the optional argument.
894
     * This will be ignored if null and defaulted by the database.
895
     */
896
    public void addOptionalArgument(String argument) {
897
        getOptionalArguments().add(new DatabaseField(argument));
898
    }
899
900
    /**
901
     * INTERNAL:
902
     * Return if there are any optional arguments.
903
     */
904
    public boolean hasOptionalArguments() {
905
        return (this.optionalArguments != null) && !this.optionalArguments.isEmpty();
906
    }
907
908
    /**
909
     * INTERNAL:
910
     * Return the list of optional arguments.
911
     * These will be ignored if null and defaulted by the database.
912
     */
913
    public List<DatabaseField> getOptionalArguments() {
914
        if (this.optionalArguments == null) {
915
            this.optionalArguments = new ArrayList<DatabaseField>();
916
        }
917
        return this.optionalArguments;
918
    }
919
920
    /**
921
     * INTERNAL:
922
     * Set the list of optional arguments.
923
     * These will be ignored if null and defaulted by the database.
924
     */
925
    public void setOptionalArguments(List<DatabaseField> optionalArguments) {
926
        this.optionalArguments = optionalArguments;
927
    }
889
}
928
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/tools/schemaframework/StoredProcedureGenerator.java (-1 / +1 lines)
Lines 107-113 Link Here
107
        while (tokenIndex != -1) {
107
        while (tokenIndex != -1) {
108
            stringWriter.write(stringToModify.substring(startIndex, tokenIndex));
108
            stringWriter.write(stringToModify.substring(startIndex, tokenIndex));
109
            startIndex = tokenIndex + 1;
109
            startIndex = tokenIndex + 1;
110
            Object parameter = call.getParameters().elementAt(nextParamIndex);
110
            Object parameter = call.getParameters().get(nextParamIndex);
111
            if (parameter instanceof DatabaseField) {
111
            if (parameter instanceof DatabaseField) {
112
                stringWriter.write(replacementToken);
112
                stringWriter.write(replacementToken);
113
                stringWriter.write(((DatabaseField)parameter).getName());
113
                stringWriter.write(((DatabaseField)parameter).getName());
(-)jpa/eclipselink.jpa.test/build.xml (-1 / +16 lines)
Lines 477-483 Link Here
477
    </target>
477
    </target>
478
478
479
    <!-- Packages JPA persistent unit test jars. -->
479
    <!-- Packages JPA persistent unit test jars. -->
480
    <target name="package" depends="config-trunk, config-flat, package-annotation, package-ddl, package-xml-only, package-xml-merge, package-xml-extended, package-validation-failed, package-jpa-advanced-field-access, package-jpa-advanced-properties, package-jpa-pu_with_spaces, package-partitioned, package-jpa-performance, package-cascade-deletes, package-jpa-metamodel, package-delimited, package-beanvalidation" description="build EclipseLink jar">
480
    <target name="package" depends="config-trunk, config-flat, package-annotation, package-ddl, package-xml-only, package-xml-merge, package-xml-extended, package-validation-failed, package-jpa-advanced-field-access, package-jpa-advanced-properties, package-jpa-pu_with_spaces, package-partitioned, package-plsql, package-jpa-performance, package-cascade-deletes, package-jpa-metamodel, package-delimited, package-beanvalidation" description="build EclipseLink jar">
481
        <jar jarfile="${eclipselink.jpa.test}/${eclipselink.tests.jar}">
481
        <jar jarfile="${eclipselink.jpa.test}/${eclipselink.tests.jar}">
482
           <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
482
           <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
483
                    includes="org/eclipse/persistence/testing/framework/**/*.class,
483
                    includes="org/eclipse/persistence/testing/framework/**/*.class,
Lines 543-548 Link Here
543
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
543
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
544
                               org/eclipse/persistence/testing/models/jpa/metamodel/**
544
                               org/eclipse/persistence/testing/models/jpa/metamodel/**
545
                               org/eclipse/persistence/testing/models/jpa/partitioned/**
545
                               org/eclipse/persistence/testing/models/jpa/partitioned/**
546
                               org/eclipse/persistence/testing/models/jpa/plsql/**
546
                               org/eclipse/persistence/testing/models/jpa/performance/**
547
                               org/eclipse/persistence/testing/models/jpa/performance/**
547
                               org/eclipse/persistence/testing/models/jpa/performance2/**
548
                               org/eclipse/persistence/testing/models/jpa/performance2/**
548
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
549
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
Lines 719-724 Link Here
719
        </jar>
720
        </jar>
720
    </target>
721
    </target>
721
722
723
    <target name="package-plsql" depends="">
724
        <copy todir="${eclipselink.jpa.test}/${build.dir}/eclipselink-plsql-model/META-INF">
725
            <fileset dir="${eclipselink.jpa.test}/resource/eclipselink-plsql-model" includes="*.xml"/>
726
        </copy>
727
        <copy todir="${eclipselink.jpa.test}/${build.dir}/eclipselink-plsql-model">
728
            <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
729
                     includes="org/eclipse/persistence/testing/models/jpa/plsql/**"/>
730
        </copy>
731
        <jar jarfile="${eclipselink.jpa.test}/eclipselink-plsql-model.jar">
732
            <fileset dir="${eclipselink.jpa.test}/${build.dir}/eclipselink-plsql-model">
733
            </fileset>
734
        </jar>
735
    </target>
736
722
    <target name="package-jpa-pu_with_multibyte" depends="">
737
    <target name="package-jpa-pu_with_multibyte" depends="">
723
        <!--copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.pu.with.multibyte}/META-INF">
738
        <!--copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.pu.with.multibyte}/META-INF">
724
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.pu.with.multibyte}" includes="*.xml"/>
739
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.pu.with.multibyte}" includes="*.xml"/>
(-)jpa/eclipselink.jpa.test/resource/eclipselink-partitioned-model/partitioned-orm.xml (-1 / +1 lines)
Lines 138-144 Link Here
138
        <inheritance strategy="JOINED"/>
138
        <inheritance strategy="JOINED"/>
139
        <discriminator-value>P</discriminator-value>
139
        <discriminator-value>P</discriminator-value>
140
        <discriminator-column name="PROJ_TYPE"/>
140
        <discriminator-column name="PROJ_TYPE"/>
141
        <range-partitioning name="RangePartitioningByPROJ_ID" union-unpartitionable-queries="true">
141
        <range-partitioning name="RangePartitioningByPROJ_ID" partition-value-type="java.lang.Integer" union-unpartitionable-queries="true">
142
            <partition-column name="PROJ_ID"/>
142
            <partition-column name="PROJ_ID"/>
143
            <partition connection-pool="default" start-value="0" end-value="1000"/>
143
            <partition connection-pool="default" start-value="0" end-value="1000"/>
144
            <partition connection-pool="node2" start-value="1000" end-value="2000"/>
144
            <partition connection-pool="node2" start-value="1000" end-value="2000"/>
(-)jpa/eclipselink.jpa.test/resource/eclipselink-plsql-model/persistence.xml (+26 lines)
Line 0 Link Here
1
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
2
    <persistence-unit name="plsql" transaction-type="RESOURCE_LOCAL">
3
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
4
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
5
        <properties>
6
            <property name="javax.persistence.jdbc.driver" value="TEST_DRIVER_CLASS"/>
7
            <property name="javax.persistence.jdbc.url" value="TEST_DATABASE_URL"/>
8
            <property name="javax.persistence.jdbc.user" value="TEST_DATABASE_USER"/>
9
            <property name="javax.persistence.jdbc.password" value="TEST_DATABASE_PASSWORD"/>
10
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
11
        </properties>
12
    </persistence-unit>
13
    <persistence-unit name="plsql-xml" transaction-type="RESOURCE_LOCAL">
14
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
15
        <mapping-file>META-INF/plsql-orm.xml</mapping-file>
16
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
17
        <properties>
18
            <property name="javax.persistence.jdbc.driver" value="TEST_DRIVER_CLASS"/>
19
            <property name="javax.persistence.jdbc.url" value="TEST_DATABASE_URL"/>
20
            <property name="javax.persistence.jdbc.user" value="TEST_DATABASE_USER"/>
21
            <property name="javax.persistence.jdbc.password" value="TEST_DATABASE_PASSWORD"/>
22
            <property name="eclipselink.orm.validate.schema" value="true"/>
23
            <!--property name="eclipselink.logging.level" value="FINEST"/-->
24
        </properties>
25
    </persistence-unit>
26
</persistence>
(-)jpa/eclipselink.jpa.test/resource/eclipselink-plsql-model/plsql-orm.xml (+46 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<entity-mappings version="2.3" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3
    <persistence-unit-metadata>
4
       <xml-mapping-metadata-complete/>
5
    </persistence-unit-metadata>
6
    <package>org.eclipse.persistence.testing.models.jpa.plsql</package>
7
    <named-plsql-stored-procedure-query name="PLSQL_SIMPLE_IN_DEFAULTS" procedure-name="PLSQL_SIMPLE_IN_DEFAULTS">
8
            <parameter query-parameter="P_VARCHAR" database-type="VARCHAR_TYPE" optional="true"/>
9
            <parameter query-parameter="P_BOOLEAN" database-type="PLSQLBoolean" optional="true"/>
10
            <parameter query-parameter="P_BINARY_INTEGER" database-type="BinaryInteger" optional="true"/>
11
            <parameter query-parameter="P_DEC" database-type="Dec" optional="true"/>
12
            <parameter query-parameter="P_INT" database-type="Int" optional="true"/>
13
            <parameter query-parameter="P_NATURAL" database-type="Natural" optional="true"/>
14
            <parameter query-parameter="P_NATURALN" database-type="NaturalN" optional="true"/>
15
            <parameter query-parameter="P_PLS_INTEGER" database-type="PLSQLInteger" optional="true"/>
16
            <parameter query-parameter="P_POSITIVE" database-type="Positive" optional="true"/>
17
            <parameter query-parameter="P_POSITIVEN" database-type="PositiveN" optional="true"/>
18
            <parameter query-parameter="P_SIGNTYPE" database-type="SignType" optional="true"/>
19
            <parameter query-parameter="P_NUMBER" database-type="Number" optional="true"/>
20
    </named-plsql-stored-procedure-query>
21
    <named-plsql-stored-procedure-query name="PLSQL_ADDRESS_OUT" procedure-name="PLSQL_ADDRESS_OUT">
22
            <parameter query-parameter="P_ADDRESS" direction="OUT" database-type="PLSQL_ADDRESS%ROWTYPE"/>
23
    </named-plsql-stored-procedure-query>
24
    <named-plsql-stored-function-query name="PLSQL_SIMPLE_IN_FUNC" function-name="PLSQL_SIMPLE_IN_FUNC">
25
            <parameter query-parameter="P_VARCHAR" database-type="VARCHAR_TYPE"/>
26
            <parameter query-parameter="P_BOOLEAN" database-type="PLSQLBoolean"/>
27
            <parameter query-parameter="P_BINARY_INTEGER" database-type="BinaryInteger"/>
28
            <parameter query-parameter="P_DEC" database-type="Dec"/>
29
            <parameter query-parameter="P_INT" database-type="Int"/>
30
            <parameter query-parameter="P_NATURAL" database-type="Natural"/>
31
            <parameter query-parameter="P_NATURALN" database-type="NaturalN"/>
32
            <parameter query-parameter="P_PLS_INTEGER" database-type="PLSQLInteger"/>
33
            <parameter query-parameter="P_POSITIVE" database-type="Positive"/>
34
            <parameter query-parameter="P_POSITIVEN" database-type="PositiveN"/>
35
            <parameter query-parameter="P_SIGNTYPE" database-type="SignType"/>
36
            <parameter query-parameter="P_NUMBER" database-type="Number"/>
37
            <return-parameter query-parameter="RESULT" database-type="PLSQLBoolean"/>
38
    </named-plsql-stored-function-query>
39
    <entity class="Employee" access="FIELD">
40
        <attributes>
41
            <id name="id"/>
42
        </attributes>
43
    </entity>
44
    <embeddable class="Address" access="FIELD"/>
45
    <embeddable class="Phone" access="FIELD"/>
46
</entity-mappings>
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/plsql/Address.java (+94 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James - initial impl
12
 ******************************************************************************/  
13
package org.eclipse.persistence.testing.models.jpa.plsql;
14
15
import java.math.BigDecimal;
16
17
import javax.persistence.Embeddable;
18
19
/**
20
 * Used to test simple PLSQL record types.
21
 * 
22
 * @author James
23
 */
24
@Embeddable
25
public class Address {
26
    protected BigDecimal id;
27
    protected Integer number;
28
    protected String street;
29
    protected String city;
30
    protected String state;
31
32
    public String getCity() {
33
        return city;
34
    }
35
36
    public void setCity(String city) {
37
        this.city = city;
38
    }
39
40
    public BigDecimal getId() {
41
        return id;
42
    }
43
44
    public void setId(BigDecimal id) {
45
        this.id = id;
46
    }
47
48
    public Integer getNumber() {
49
        return number;
50
    }
51
52
    public void setNumber(Integer number) {
53
        this.number = number;
54
    }
55
56
    public String getStreet() {
57
        return street;
58
    }
59
60
    public void setStreet(String street) {
61
        this.street = street;
62
    }
63
64
    public String getState() {
65
        return state;
66
    }
67
68
    public void setState(String state) {
69
        this.state = state;
70
    }
71
    
72
    public boolean equals(Object object) {
73
    	if (!(object instanceof Address)) {
74
    		return false;
75
    	}
76
    	Address address = (Address)object;
77
    	if (this.id != null && !this.id.equals(address.id)) {
78
    		return false;
79
    	}
80
    	if (this.number != null && !this.number.equals(address.number)) {
81
    		return false;
82
    	}
83
    	if (this.street != null && !this.street.equals(address.street)) {
84
    		return false;
85
    	}
86
    	if (this.city != null && !this.city.equals(address.city)) {
87
    		return false;
88
    	}
89
    	if (this.state != null && !this.state.equals(address.state)) {
90
    		return false;
91
    	}
92
    	return true;
93
    }
94
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/plsql/Employee.java (+135 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James - initial impl
12
 ******************************************************************************/  
13
package org.eclipse.persistence.testing.models.jpa.plsql;
14
15
import java.math.BigDecimal;
16
import java.util.ArrayList;
17
import java.util.List;
18
19
import javax.persistence.Entity;
20
import javax.persistence.Id;
21
22
import org.eclipse.persistence.annotations.Direction;
23
import org.eclipse.persistence.platform.database.oracle.annotations.NamedPLSQLStoredFunctionQuery;
24
import org.eclipse.persistence.platform.database.oracle.annotations.NamedPLSQLStoredProcedureQueries;
25
import org.eclipse.persistence.platform.database.oracle.annotations.NamedPLSQLStoredProcedureQuery;
26
import org.eclipse.persistence.platform.database.oracle.annotations.PLSQLParameter;
27
28
@NamedPLSQLStoredProcedureQueries({
29
    @NamedPLSQLStoredProcedureQuery(
30
            name="PLSQL_SIMPLE_IN_DEFAULTS",
31
            procedureName="PLSQL_SIMPLE_IN_DEFAULTS",
32
            parameters={
33
                    @PLSQLParameter(queryParameter="P_VARCHAR", databaseType="VARCHAR_TYPE", optional=true),
34
                    @PLSQLParameter(queryParameter="P_BOOLEAN", databaseType="PLSQLBoolean", optional=true),
35
                    @PLSQLParameter(queryParameter="P_BINARY_INTEGER", databaseType="BinaryInteger", optional=true),
36
                    @PLSQLParameter(queryParameter="P_DEC", databaseType="Dec", optional=true),
37
                    @PLSQLParameter(queryParameter="P_INT", databaseType="Int", optional=true),
38
                    @PLSQLParameter(queryParameter="P_NATURAL", databaseType="Natural", optional=true),
39
                    @PLSQLParameter(queryParameter="P_NATURALN", databaseType="NaturalN", optional=true),
40
                    @PLSQLParameter(queryParameter="P_PLS_INTEGER", databaseType="PLSQLInteger", optional=true),
41
                    @PLSQLParameter(queryParameter="P_POSITIVE", databaseType="Positive", optional=true),
42
                    @PLSQLParameter(queryParameter="P_POSITIVEN", databaseType="PositiveN", optional=true),
43
                    @PLSQLParameter(queryParameter="P_SIGNTYPE", databaseType="SignType", optional=true),
44
                    @PLSQLParameter(queryParameter="P_NUMBER", databaseType="Number", optional=true)
45
            }
46
    ),
47
    @NamedPLSQLStoredProcedureQuery(
48
            name="PLSQL_ADDRESS_OUT",
49
            procedureName="PLSQL_ADDRESS_OUT",
50
            parameters={
51
                    @PLSQLParameter(queryParameter="P_ADDRESS", direction=Direction.OUT, databaseType="PLSQL_ADDRESS%ROWTYPE")
52
            }
53
    )
54
})
55
@NamedPLSQLStoredFunctionQuery(
56
        name="PLSQL_SIMPLE_IN_FUNC",
57
        functionName="PLSQL_SIMPLE_IN_FUNC",
58
        parameters={
59
                @PLSQLParameter(queryParameter="P_VARCHAR", databaseType="VARCHAR_TYPE"),
60
                @PLSQLParameter(queryParameter="P_BOOLEAN", databaseType="PLSQLBoolean"),
61
                @PLSQLParameter(queryParameter="P_BINARY_INTEGER", databaseType="BinaryInteger"),
62
                @PLSQLParameter(queryParameter="P_DEC", databaseType="Dec"),
63
                @PLSQLParameter(queryParameter="P_INT", databaseType="Int"),
64
                @PLSQLParameter(queryParameter="P_NATURAL", databaseType="Natural"),
65
                @PLSQLParameter(queryParameter="P_NATURALN", databaseType="NaturalN"),
66
                @PLSQLParameter(queryParameter="P_PLS_INTEGER", databaseType="PLSQLInteger"),
67
                @PLSQLParameter(queryParameter="P_POSITIVE", databaseType="Positive"),
68
                @PLSQLParameter(queryParameter="P_POSITIVEN", databaseType="PositiveN"),
69
                @PLSQLParameter(queryParameter="P_SIGNTYPE", databaseType="SignType"),
70
                @PLSQLParameter(queryParameter="P_NUMBER", databaseType="Number")
71
        },
72
        returnParameter=@PLSQLParameter(queryParameter="RESULT", direction=Direction.OUT, databaseType="PLSQLBoolean")
73
)
74
/**
75
 * Used to test simple PLSQL record types.
76
 * 
77
 * @author James
78
 */
79
@Entity
80
public class Employee {
81
    @Id
82
    protected BigDecimal id;
83
    protected String name;
84
    protected boolean active;
85
    protected Address address;
86
    protected List<Phone> phones = new ArrayList<Phone>();
87
    
88
	public BigDecimal getId() {
89
		return id;
90
	}
91
	public void setId(BigDecimal id) {
92
		this.id = id;
93
	}
94
	public String getName() {
95
		return name;
96
	}
97
	public void setName(String name) {
98
		this.name = name;
99
	}
100
	public Address getAddress() {
101
		return address;
102
	}
103
	public void setAddress(Address address) {
104
		this.address = address;
105
	}
106
	public List<Phone> getPhones() {
107
		return phones;
108
	}
109
	public void setPhones(List<Phone> phones) {
110
		this.phones = phones;
111
	}
112
    
113
    public boolean equals(Object object) {
114
    	if (!(object instanceof Employee)) {
115
    		return false;
116
    	}
117
    	Employee employee = (Employee)object;
118
    	if (this.id != null && !this.id.equals(employee.id)) {
119
    		return false;
120
    	}
121
    	if (this.name != null && !this.name.equals(employee.name)) {
122
    		return false;
123
    	}
124
    	if (this.address != null && !this.address.equals(employee.address)) {
125
    		return false;
126
    	}
127
    	return true;
128
    }
129
	public boolean isActive() {
130
		return active;
131
	}
132
	public void setActive(boolean active) {
133
		this.active = active;
134
	}
135
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/plsql/Phone.java (+56 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James - initial impl
12
 ******************************************************************************/  
13
package org.eclipse.persistence.testing.models.jpa.plsql;
14
15
import javax.persistence.Embeddable;
16
17
/**
18
 * Used to test simple PLSQL record types.
19
 * 
20
 * @author James
21
 */
22
@Embeddable
23
public class Phone {
24
    protected String areaCode;
25
    protected String number;
26
    
27
    public String getAreaCode() {
28
		return areaCode;
29
	}
30
31
	public void setAreaCode(String areaCode) {
32
		this.areaCode = areaCode;
33
	}
34
35
	public String getNumber() {
36
		return number;
37
	}
38
39
	public void setNumber(String number) {
40
		this.number = number;
41
	}
42
43
	public boolean equals(Object object) {
44
    	if (!(object instanceof Phone)) {
45
    		return false;
46
    	}
47
    	Phone address = (Phone)object;
48
    	if (this.areaCode != null && !this.areaCode.equals(address.areaCode)) {
49
    		return false;
50
    	}
51
    	if (this.number != null && !this.number.equals(address.number)) {
52
    		return false;
53
    	}
54
    	return true;
55
    }
56
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/AdvancedJPAJunitTest.java (-1 / +4 lines)
Lines 270-276 Link Here
270
        try {
270
        try {
271
            query = em.createNamedQuery("StoredFunction_In");
271
            query = em.createNamedQuery("StoredFunction_In");
272
            query.setParameter("P_IN", 1);
272
            query.setParameter("P_IN", 1);
273
            query.getResultList();
273
            int result = (Integer)query.getSingleResult();
274
            if (result != 1000) {
275
                fail("Incorrect result returned:" + result);
276
            }
274
        } finally {
277
        } finally {
275
            closeEntityManager(em);
278
            closeEntityManager(em);
276
        }
279
        }
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/FullRegressionTestSuite.java (+4 lines)
Lines 57-62 Link Here
57
57
58
import org.eclipse.persistence.testing.tests.jpa.partitioned.PartitionedTestSuite;
58
import org.eclipse.persistence.testing.tests.jpa.partitioned.PartitionedTestSuite;
59
import org.eclipse.persistence.testing.tests.jpa.partitioned.PartitionedXMLTestSuite;
59
import org.eclipse.persistence.testing.tests.jpa.partitioned.PartitionedXMLTestSuite;
60
import org.eclipse.persistence.testing.tests.jpa.plsql.PLSQLTestSuite;
61
import org.eclipse.persistence.testing.tests.jpa.plsql.XMLPLSQLTestSuite;
60
import org.eclipse.persistence.testing.tests.jpa.relationships.EMQueryJUnitTestSuite;
62
import org.eclipse.persistence.testing.tests.jpa.relationships.EMQueryJUnitTestSuite;
61
import org.eclipse.persistence.testing.tests.jpa.relationships.ExpressionJUnitTestSuite;
63
import org.eclipse.persistence.testing.tests.jpa.relationships.ExpressionJUnitTestSuite;
62
import org.eclipse.persistence.testing.tests.jpa.relationships.IsolatedCacheTestSuite;
64
import org.eclipse.persistence.testing.tests.jpa.relationships.IsolatedCacheTestSuite;
Lines 286-291 Link Here
286
288
287
        fullSuite.addTest(PartitionedTestSuite.suite());
289
        fullSuite.addTest(PartitionedTestSuite.suite());
288
        fullSuite.addTest(PartitionedXMLTestSuite.suite());
290
        fullSuite.addTest(PartitionedXMLTestSuite.suite());
291
        fullSuite.addTest(PLSQLTestSuite.suite());
292
        fullSuite.addTest(XMLPLSQLTestSuite.suite());
289
293
290
        return fullSuite;
294
        return fullSuite;
291
    }
295
    }
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/plsql/PLSQLTestSuite.java (+310 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James Sutherland (Oracle) - initial impl
12
 ******************************************************************************/ 
13
package org.eclipse.persistence.testing.tests.jpa.plsql;
14
15
import javax.persistence.EntityManager;
16
import javax.persistence.Query;
17
18
import junit.framework.*;
19
20
import org.eclipse.persistence.sessions.DatabaseSession;
21
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
22
23
public class PLSQLTestSuite extends JUnitTestCase {
24
    public static boolean validDatabase = true;
25
        
26
    public static Test suite() {
27
        TestSuite suite = new TestSuite("PLSQLTests");
28
        suite.addTest(new PLSQLTestSuite("testSetup"));
29
        suite.addTest(new PLSQLTestSuite("testSimpleProcedure"));
30
        suite.addTest(new PLSQLTestSuite("testSimpleFunction"));
31
        suite.addTest(new PLSQLTestSuite("testRecordOut"));
32
        return suite;
33
    }
34
    
35
    public PLSQLTestSuite(String name) {
36
        super(name);
37
    }
38
    
39
    /**
40
     * Return the name of the persistence context this test uses.
41
     * This allow a subclass test to set this only in one place.
42
     */
43
    @Override
44
    public String getPersistenceUnitName() {
45
        return "plsql";
46
    }
47
    
48
    /**
49
     * The setup is done as a test, both to record its failure, and to allow execution in the server.
50
     */
51
    public void testSetup() {
52
        if (!getServerSession().getPlatform().isOracle()) {
53
            warning("This test can only be run on Oracle.");
54
            return;
55
        }
56
        createTables(getDatabaseSession());
57
    }
58
    
59
    public void createTables(DatabaseSession session) {
60
        // Tables
61
        try {
62
            session.executeNonSelectingSQL("DROP TABLE PLSQL_ADDRESS");
63
        } catch (Exception ignore) {}
64
        session.executeNonSelectingSQL("CREATE TABLE PLSQL_ADDRESS ("
65
                + "ADDRESS_ID NUMBER(10) NOT NULL, STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(30), PRIMARY KEY (ADDRESS_ID))");
66
        session.executeNonSelectingSQL("INSERT INTO PLSQL_ADDRESS ("
67
                + "ADDRESS_ID, CITY) values (1234, 'Ottawa')");
68
        
69
        // Procedures
70
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_IN(P_VARCHAR IN VARCHAR2 DEFAULT '', P_BOOLEAN IN BOOLEAN, P_BINARY_INTEGER IN BINARY_INTEGER, "
71
                        + "P_DEC IN DEC, P_INT IN INT, P_NATURAL IN NATURAL, P_NATURALN IN NATURALN, "
72
                        + "P_PLS_INTEGER IN PLS_INTEGER, P_POSITIVE IN POSITIVE, P_POSITIVEN IN POSITIVEN, P_SIGNTYPE IN SIGNTYPE, P_NUMBER IN NUMBER) AS "                
73
                + "BEGIN NULL; END;");
74
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_IN_DEFAULTS(P_VARCHAR IN VARCHAR2 DEFAULT '', P_BOOLEAN IN BOOLEAN DEFAULT TRUE, P_BINARY_INTEGER IN BINARY_INTEGER DEFAULT 0, "
75
                + "P_DEC IN DEC DEFAULT 0, P_INT IN INT DEFAULT 0, P_NATURAL IN NATURAL DEFAULT 1, P_NATURALN IN NATURALN DEFAULT 1, "
76
                + "P_PLS_INTEGER IN PLS_INTEGER DEFAULT 0, P_POSITIVE IN POSITIVE DEFAULT 1, P_POSITIVEN IN POSITIVEN DEFAULT 1, P_SIGNTYPE IN SIGNTYPE DEFAULT 1, P_NUMBER IN NUMBER DEFAULT 0) AS "                
77
        + "BEGIN NULL; END;");
78
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_OUT(P_VARCHAR OUT VARCHAR2, P_BOOLEAN OUT BOOLEAN, P_BINARY_INTEGER OUT BINARY_INTEGER, "
79
                        + "P_DEC OUT DEC, P_INT OUT INT, P_NATURAL OUT NATURAL, " //P_NATURALN OUT NATURALN, "
80
                        + "P_PLS_INTEGER OUT PLS_INTEGER, P_POSITIVE OUT POSITIVE, " //P_POSITIVEN OUT POSITIVEN, "
81
                        + "P_SIGNTYPE OUT SIGNTYPE, P_NUMBER OUT NUMBER) AS "                
82
                + "BEGIN P_VARCHAR := 'varchar'; P_BOOLEAN := true; P_BINARY_INTEGER := 123; "
83
                + "P_DEC := 1; P_INT := 1; P_NATURAL := 1; " //P_NATURALN := 1; "
84
                        + "P_PLS_INTEGER := 1; P_POSITIVE := 1; " //P_POSITIVEN := 1; "
85
                        + "P_SIGNTYPE := 1; P_NUMBER := 123; \n"
86
                + "END;");
87
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_SIMPLE_INOUT(P_VARCHAR IN OUT VARCHAR2, P_BOOLEAN IN OUT BOOLEAN, P_BINARY_INTEGER IN OUT BINARY_INTEGER, "
88
                        + "P_DEC IN OUT DEC, P_INT IN OUT INT, P_NATURAL IN OUT NATURAL, P_NATURALN IN OUT NATURALN, "
89
                        + "P_PLS_INTEGER IN OUT PLS_INTEGER, P_POSITIVE IN OUT POSITIVE, P_POSITIVEN IN OUT POSITIVEN, P_SIGNTYPE IN OUT SIGNTYPE, P_NUMBER IN OUT NUMBER) AS "                
90
                + "BEGIN NULL; END;");
91
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_IN(P_ADDRESS IN PLSQL_ADDRESS%ROWTYPE) AS "
92
                + "BEGIN NULL; END;");
93
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_IN_DATA(P_ADDRESS IN PLSQL_ADDRESS%ROWTYPE, P_LOCAL IN VARCHAR2) AS "
94
                + "BEGIN NULL; END;");
95
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_OUT(P_ADDRESS OUT PLSQL_ADDRESS%ROWTYPE) AS "
96
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON';  END;");
97
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_OUT_DATA(P_ADDRESS OUT PLSQL_ADDRESS%ROWTYPE, P_LOCAL OUT VARCHAR2) AS "
98
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON'; P_LOCAL := 'Local';  END;");
99
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_INOUT(P_ADDRESS IN OUT PLSQL_ADDRESS%ROWTYPE) AS "
100
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON';  END;");
101
        session.executeNonSelectingSQL("CREATE OR REPLACE PROCEDURE PLSQL_ADDRESS_INOUT_DATA(P_ADDRESS IN OUT PLSQL_ADDRESS%ROWTYPE, P_LOCAL IN OUT VARCHAR2) AS "
102
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON'; P_LOCAL := 'Local';  END;");
103
104
        // Functions
105
        session.executeNonSelectingSQL("CREATE OR REPLACE FUNCTION PLSQL_SIMPLE_IN_FUNC(P_VARCHAR IN VARCHAR2, P_BOOLEAN IN BOOLEAN, P_BINARY_INTEGER IN BINARY_INTEGER, "
106
                        + "P_DEC IN DEC, P_INT IN INT, P_NATURAL IN NATURAL, P_NATURALN IN NATURALN, "
107
                        + "P_PLS_INTEGER IN PLS_INTEGER, P_POSITIVE IN POSITIVE, P_POSITIVEN IN POSITIVEN, P_SIGNTYPE IN SIGNTYPE, P_NUMBER IN NUMBER) RETURN BOOLEAN AS "                
108
                + "BEGIN RETURN TRUE; END;");
109
        session.executeNonSelectingSQL("CREATE OR REPLACE FUNCTION PLSQL_ADDRESS_OUT_FUNC RETURN PLSQL_ADDRESS%ROWTYPE AS "
110
                + " P_ADDRESS PLSQL_ADDRESS%ROWTYPE; "
111
                + "BEGIN P_ADDRESS.ADDRESS_ID := 1234; P_ADDRESS.STREET_NUM := 17; P_ADDRESS.STREET := 'Bank'; P_ADDRESS.CITY := 'Ottawa'; P_ADDRESS.STATE := 'ON';  RETURN P_ADDRESS; END;");
112
     
113
        // Types
114
        try {
115
            session.executeNonSelectingSQL("DROP TYPE PLSQL_P_PLSQL_EMP_REC FORCE");
116
        } catch (Exception ignore) {}
117
        try {
118
            session.executeNonSelectingSQL("DROP TYPE PLSQL_P_PLSQL_ADDRESS_REC FORCE");
119
        } catch (Exception ignore) {}
120
        try {
121
            session.executeNonSelectingSQL("DROP TYPE PLSQL_P_PLSQL_PHONE_REC FORCE");
122
        } catch (Exception ignore) {}
123
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_ADDRESS_REC AS OBJECT ("
124
                + "ADDRESS_ID NUMBER(10), STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(2))");
125
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_PHONE_REC AS OBJECT ("
126
                + "AREA_CODE VARCHAR2(3), P_NUM VARCHAR2(7))");
127
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_PHONE_LIST AS VARRAY(30) OF PLSQL_P_PLSQL_PHONE_REC");
128
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_EMP_REC AS OBJECT ("
129
                + "EMP_ID NUMBER(10), NAME VARCHAR2(30), ACTIVE NUMBER(1), ADDRESS PLSQL_P_PLSQL_ADDRESS_REC, PHONES PLSQL_P_PLSQL_PHONE_LIST)");
130
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_CITY_LIST AS VARRAY(255) OF VARCHAR2(100)");
131
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_ADDRESS_LIST AS VARRAY(255) OF PLSQL_P_PLSQL_ADDRESS_REC");
132
        session.executeNonSelectingSQL("CREATE OR REPLACE TYPE PLSQL_P_PLSQL_EMP_LIST AS VARRAY(255) OF PLSQL_P_PLSQL_EMP_REC");
133
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE PLSQL_P AS \n"
134
                    + "TYPE PLSQL_ADDRESS_REC IS RECORD (ADDRESS_ID NUMBER(10), STREET_NUM NUMBER(10), STREET VARCHAR2(30), CITY VARCHAR2(30), STATE VARCHAR2(2)); \n"
135
                    + "TYPE PLSQL_ADDRESS_CUR IS REF CURSOR RETURN PLSQL_ADDRESS%ROWTYPE; \n"
136
                    + "TYPE PLSQL_ADDRESS_REC_CUR IS REF CURSOR RETURN PLSQL_ADDRESS_REC; \n"
137
                    + "TYPE PLSQL_PHONE_REC IS RECORD (AREA_CODE VARCHAR2(3), P_NUM VARCHAR2(7)); \n"
138
                    + "TYPE PLSQL_PHONE_LIST IS TABLE OF PLSQL_PHONE_REC INDEX BY BINARY_INTEGER; \n"
139
                    + "TYPE PLSQL_EMP_REC IS RECORD (EMP_ID NUMBER(10), NAME VARCHAR2(30), ACTIVE BOOLEAN, ADDRESS PLSQL_ADDRESS_REC, PHONES PLSQL_PHONE_LIST); \n"
140
                    + "TYPE PLSQL_CITY_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER; \n"
141
                    + "TYPE PLSQL_ADDRESS_LIST IS TABLE OF PLSQL_ADDRESS_REC INDEX BY BINARY_INTEGER; \n"
142
                    + "TYPE PLSQL_EMP_LIST IS TABLE OF PLSQL_EMP_REC INDEX BY BINARY_INTEGER; \n"
143
                    + "PROCEDURE PLSQL_CITY_LIST_IN(P_CITY_LIST IN PLSQL_CITY_LIST, P_CITY IN VARCHAR2); \n"
144
                    + "PROCEDURE PLSQL_CITY_LIST_OUT(P_CITY_LIST OUT PLSQL_CITY_LIST, P_CITY OUT VARCHAR2); \n"
145
                    + "PROCEDURE PLSQL_CITY_LIST_INOUT(P_CITY_LIST IN OUT PLSQL_CITY_LIST, P_CITY IN OUT VARCHAR2); \n"
146
                    + "PROCEDURE PLSQL_ADDRESS_LIST_IN(P_ADDRESS_LIST IN PLSQL_ADDRESS_LIST, P_CITY IN VARCHAR2); \n"
147
                    + "PROCEDURE PLSQL_ADDRESS_LIST_OUT(P_ADDRESS_LIST OUT PLSQL_ADDRESS_LIST, P_CITY OUT VARCHAR2); \n"
148
                    + "PROCEDURE PLSQL_ADDRESS_LIST_INOUT(P_ADDRESS_LIST IN OUT PLSQL_ADDRESS_LIST, P_CITY IN OUT VARCHAR2); \n"
149
                    + "PROCEDURE PLSQL_EMP_LIST_IN(P_EMP_LIST IN PLSQL_EMP_LIST, P_CITY IN VARCHAR2); \n"
150
                    + "PROCEDURE PLSQL_EMP_LIST_OUT(P_EMP_LIST OUT PLSQL_EMP_LIST, P_CITY OUT VARCHAR2); \n"
151
                    + "PROCEDURE PLSQL_EMP_LIST_INOUT(P_EMP_LIST IN OUT PLSQL_EMP_LIST, P_CITY IN OUT VARCHAR2); \n"
152
                    + "PROCEDURE PLSQL_EMP_IN(P_EMP IN PLSQL_EMP_REC, P_CITY IN VARCHAR2); \n"
153
                    + "PROCEDURE PLSQL_EMP_OUT(P_EMP OUT PLSQL_EMP_REC, P_CITY OUT VARCHAR2); \n"
154
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2); \n"
155
                    + "PROCEDURE PLSQL_ADDRESS_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_CUR); \n"
156
                    + "PROCEDURE PLSQL_ADDRESS_REC_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_REC_CUR); \n"
157
                    + "END PLSQL_P; \n");
158
        session.executeNonSelectingSQL("CREATE OR REPLACE PACKAGE BODY PLSQL_P AS \n"
159
                    + "PROCEDURE PLSQL_CITY_LIST_IN(P_CITY_LIST IN PLSQL_CITY_LIST, P_CITY IN VARCHAR2) AS \n"
160
                        + "BEGIN \n"
161
                        + "NULL; \n"
162
                        + "END PLSQL_CITY_LIST_IN; \n"
163
                    + "PROCEDURE PLSQL_CITY_LIST_OUT(P_CITY_LIST OUT PLSQL_CITY_LIST, P_CITY OUT VARCHAR2) AS \n"
164
                        + "BEGIN \n"
165
                        + "P_CITY := 'Nepean'; \n"
166
                        + "P_CITY_LIST(1) := 'Ottawa'; \n"
167
                        + "END PLSQL_CITY_LIST_OUT; \n"
168
                    + "PROCEDURE PLSQL_CITY_LIST_INOUT(P_CITY_LIST IN OUT PLSQL_CITY_LIST, P_CITY IN OUT VARCHAR2) AS \n"
169
                        + "BEGIN \n"
170
                        + "P_CITY := 'Nepean'; \n"
171
                        + "P_CITY_LIST(1) := 'Ottawa'; \n"
172
                        + "END PLSQL_CITY_LIST_INOUT; \n"
173
                    + "PROCEDURE PLSQL_ADDRESS_LIST_IN(P_ADDRESS_LIST IN PLSQL_ADDRESS_LIST, P_CITY IN VARCHAR2) AS \n"
174
                        + "BEGIN \n"
175
                        + "NULL; \n"
176
                        + "END PLSQL_ADDRESS_LIST_IN; \n"
177
                    + "PROCEDURE PLSQL_ADDRESS_LIST_OUT(P_ADDRESS_LIST OUT PLSQL_ADDRESS_LIST, P_CITY OUT VARCHAR2) AS \n"
178
                        + "BEGIN \n"
179
                        + "P_CITY := 'Nepean'; "
180
                        + "END PLSQL_ADDRESS_LIST_OUT; \n"
181
                    + "PROCEDURE PLSQL_ADDRESS_LIST_INOUT(P_ADDRESS_LIST IN OUT PLSQL_ADDRESS_LIST, P_CITY IN OUT VARCHAR2) AS \n"
182
                        + "BEGIN \n"
183
                        + "P_CITY := 'Nepean'; \n"
184
                        + "END PLSQL_ADDRESS_LIST_INOUT; \n"
185
                    + "PROCEDURE PLSQL_EMP_LIST_IN(P_EMP_LIST IN PLSQL_EMP_LIST, P_CITY IN VARCHAR2) AS \n"
186
                        + "BEGIN \n"
187
                        + "NULL; \n"
188
                        + "END PLSQL_EMP_LIST_IN; \n"
189
                    + "PROCEDURE PLSQL_EMP_LIST_OUT(P_EMP_LIST OUT PLSQL_EMP_LIST, P_CITY OUT VARCHAR2) AS \n"
190
                        + "BEGIN \n"
191
                        + "P_CITY := 'Nepean'; "
192
                        + "END PLSQL_EMP_LIST_OUT; \n"
193
                    + "PROCEDURE PLSQL_EMP_LIST_INOUT(P_EMP_LIST IN OUT PLSQL_EMP_LIST, P_CITY IN OUT VARCHAR2) AS \n"
194
                        + "BEGIN \n"
195
                        + "P_CITY := 'Nepean'; "
196
                        + "END PLSQL_EMP_LIST_INOUT; \n"
197
                    + "PROCEDURE PLSQL_EMP_IN(P_EMP IN PLSQL_EMP_REC, P_CITY IN VARCHAR2) AS \n"
198
                        + "BEGIN \n"
199
                        + "NULL; \n"
200
                        + "END PLSQL_EMP_IN; \n"
201
                    + "PROCEDURE PLSQL_EMP_OUT(P_EMP OUT PLSQL_EMP_REC, P_CITY OUT VARCHAR2) AS \n"
202
                        + "BEGIN \n"
203
                        + "P_CITY := 'Nepean'; "
204
                        + "END PLSQL_EMP_OUT; \n"
205
                    + "PROCEDURE PLSQL_EMP_INOUT(P_EMP IN OUT PLSQL_EMP_REC, P_CITY IN OUT VARCHAR2) AS \n"
206
                        + "BEGIN \n"
207
                        + "P_CITY := 'Nepean'; \n"
208
                        + "END PLSQL_EMP_INOUT; \n"
209
                    + "PROCEDURE PLSQL_ADDRESS_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_CUR) AS \n"
210
                        + "BEGIN \n"
211
                        + "OPEN P_ADDRESS FOR SELECT * FROM PLSQL_ADDRESS; \n"
212
                        + "END PLSQL_ADDRESS_CUR_OUT; \n"
213
                    + "PROCEDURE PLSQL_ADDRESS_REC_CUR_OUT(P_ADDRESS OUT PLSQL_ADDRESS_REC_CUR) AS \n"
214
                        + "BEGIN \n"
215
                        + "OPEN P_ADDRESS FOR SELECT * FROM PLSQL_ADDRESS; \n"
216
                        + "END PLSQL_ADDRESS_REC_CUR_OUT; \n"
217
                    + "END PLSQL_P; \n");
218
    }
219
    
220
    /**
221
     * Test a simple procedure.
222
     */
223
    public void testSimpleProcedure() {
224
        if (!getServerSession().getPlatform().isOracle()) {
225
            return;
226
        }
227
        EntityManager em = createEntityManager();
228
        beginTransaction(em);
229
        try {
230
            Query query = em.createNamedQuery("PLSQL_SIMPLE_IN_DEFAULTS");
231
            query.setParameter("P_VARCHAR", "test");
232
            query.executeUpdate();
233
            query = em.createNamedQuery("PLSQL_SIMPLE_IN_DEFAULTS");
234
            query.setParameter("P_BOOLEAN", true);
235
            query.executeUpdate();
236
            query = em.createNamedQuery("PLSQL_SIMPLE_IN_DEFAULTS");
237
            query.setParameter("P_VARCHAR", "test");
238
            query.setParameter("P_BOOLEAN", true);
239
            query.setParameter("P_BINARY_INTEGER", 1);
240
            query.setParameter("P_DEC", 1);
241
            query.setParameter("P_INT", 1);
242
            query.setParameter("P_NATURAL", 1);
243
            query.setParameter("P_NATURALN", 1);
244
            query.setParameter("P_PLS_INTEGER", 1);
245
            query.setParameter("P_POSITIVE", 1);
246
            query.setParameter("P_POSITIVEN", 1);
247
            query.setParameter("P_SIGNTYPE", 1);
248
            query.setParameter("P_NUMBER", 1);
249
            query.executeUpdate();
250
            query.executeUpdate();
251
            query = em.createNamedQuery("PLSQL_SIMPLE_IN_DEFAULTS");
252
            query.setParameter("P_BOOLEAN", true);
253
            query.executeUpdate();
254
        } finally {
255
            closeEntityManagerAndTransaction(em);
256
        }
257
    }
258
    
259
    /**
260
     * Test a simple function.
261
     */
262
    public void testSimpleFunction() {
263
        if (!getServerSession().getPlatform().isOracle()) {
264
            return;
265
        }
266
        EntityManager em = createEntityManager();
267
        beginTransaction(em);
268
        try {
269
            Query query = em.createNamedQuery("PLSQL_SIMPLE_IN_FUNC");
270
            query.setParameter("P_VARCHAR", "test");
271
            query.setParameter("P_BOOLEAN", true);
272
            query.setParameter("P_BINARY_INTEGER", 1);
273
            query.setParameter("P_DEC", 1);
274
            query.setParameter("P_INT", 1);
275
            query.setParameter("P_NATURAL", 1);
276
            query.setParameter("P_NATURALN", 1);
277
            query.setParameter("P_PLS_INTEGER", 1);
278
            query.setParameter("P_POSITIVE", 1);
279
            query.setParameter("P_POSITIVEN", 1);
280
            query.setParameter("P_SIGNTYPE", 1);
281
            query.setParameter("P_NUMBER", 1);
282
            int result = (Integer)query.getSingleResult();
283
            if (result != 1) {
284
                fail("Incorrect result.");
285
            }
286
        } finally {
287
            closeEntityManagerAndTransaction(em);
288
        }
289
    }
290
    
291
    /**
292
     * Test a record out procedure.
293
     */
294
    public void testRecordOut() {
295
        if (!getServerSession().getPlatform().isOracle()) {
296
            return;
297
        }
298
        EntityManager em = createEntityManager();
299
        beginTransaction(em);
300
        try {
301
            Query query = em.createNamedQuery("PLSQL_ADDRESS_OUT");
302
            Object result = query.getSingleResult();
303
            if (result == null) {
304
                fail("Incorrect result.");
305
            }
306
        } finally {
307
            closeEntityManagerAndTransaction(em);
308
        }
309
    }
310
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/plsql/XMLPLSQLTestSuite.java (+42 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James Sutherland (Oracle) - initial impl
12
 ******************************************************************************/ 
13
package org.eclipse.persistence.testing.tests.jpa.plsql;
14
15
import junit.framework.*;
16
17
public class XMLPLSQLTestSuite extends PLSQLTestSuite {
18
    public static boolean validDatabase = true;
19
        
20
    public static Test suite() {
21
        TestSuite suite = new TestSuite("XMLPLSQLTestSuite");
22
        suite.addTest(new XMLPLSQLTestSuite("testSetup"));
23
        suite.addTest(new XMLPLSQLTestSuite("testSimpleProcedure"));
24
        suite.addTest(new XMLPLSQLTestSuite("testSimpleFunction"));
25
        suite.addTest(new XMLPLSQLTestSuite("testRecordOut"));
26
        return suite;
27
    }
28
    
29
    public XMLPLSQLTestSuite(String name) {
30
        super(name);
31
    }
32
    
33
    /**
34
     * Return the name of the persistence context this test uses.
35
     * This allow a subclass test to set this only in one place.
36
     */
37
    @Override
38
    public String getPersistenceUnitName() {
39
        return "plsql-xml";
40
    }
41
42
}

Return to bug 339905