|
Как получить Connection из EntityManager?
#37837297
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
Кажется получилось... Хотелось бы обсудить это.
Тестовый код такой:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46.
EntityManager ems=oracleCoreFactory.getNewConnection();
EntityManagerImpl d=(EntityManagerImpl)ems.getDelegate();
ServerSession s=d.getServerSession();
Accessor a=s.getAccessor();
Connection con=a.getConnection();
if(con!=null){
ArrayList<HashMap<String,Object>> ret=
(ArrayList<HashMap<String,Object>>)
oracleCoreFactory.exec_sql_proc(
new ExecParameters(
new FunctionToCall("test.debug_try_insert_into_temp"),
new InputParameters(new String[]{"Hello Jack!!!"}),
new InputParametersTypes(new Class[]{java.lang.String.class}),
new OutputParameters(new String[]{"out_str"}),
new OutputParametersTypes(new Class[]{java.lang.String.class}),
new FunctionOutputType(OracleTypes.CURSOR)
),con
);
HashMap<String, String> retMap = new HashMap<String, String>();
CriteriaBuilder criteriaBuilder = ems.getCriteriaBuilder();
CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
Root<DebugTest> from = criteriaQuery.from(DebugTest.class);
CriteriaQuery<Object> select = criteriaQuery.select(from);
TypedQuery<Object> typedQuery = ems.createQuery(select);
List<DebugTest> DebugTestList = (List<DebugTest>) ((List) typedQuery.getResultList());
try {
con.close();
} catch (SQLException ex) {
Logger.getLogger(OracleTempXmlFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
oracleCoreFactory.closeConnection();
Хранимая процедура Oracle:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
function debug_try_insert_into_temp(some_str in varchar2) return sys_refcursor AS
resc sys_refcursor;
begin
insert into debug_test values(0,some_str||' 0');
insert into debug_test values(1,some_str||' 1');
insert into debug_test values(2,some_str||' 2');
insert into debug_test values(3,some_str||' 3');
insert into debug_test values(4,some_str||' 4');
insert into debug_test values(5,some_str||' 5');
insert into debug_test values(6,some_str||' 6');
insert into debug_test values(7,some_str||' 7');
begin open resc for
select 2 as out_str from dual;
end;
return resc;
end debug_try_insert_into_temp;
Как получается соединение:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
@Override
public EntityManager getNewConnection() {
if ((EntityManagerFactoryForSave == null) || (!EntityManagerFactoryForSave.isOpen())) {
EntityManagerFactoryForSave = Persistence.createEntityManagerFactory("ServerPUsave");
}
if ((ems == null) || (!ems.isOpen())) {
Map properties = new HashMap();
properties.put("javax.persistence.jdbc.user", IMCConfigs.getConfig(IMCConfigs.SERVER_SQL_USER));
properties.put("javax.persistence.jdbc.password", IMCConfigs.getConfig(IMCConfigs.SERVER_SQL_PASSWORD));
properties.put("javax.persistence.jdbc.url", IMCConfigs.getConfig(IMCConfigs.SERVER_SQL_URL));
properties.put("eclipselink.jdbc.exclusive-connection.mode", "Always");
properties.put("eclipselink.jdbc.exclusive-connection.is-lazy", "false");
ems = EntityManagerFactoryForSave.createEntityManager(properties);
}
factoryStack.add(true);
return ems;
}
@Override
public void closeConnection() {
if ((ems != null) && (ems.isOpen())) {
ems.close();
}
if ((EntityManagerFactoryForSave != null) && (EntityManagerFactoryForSave.isOpen())) {
EntityManagerFactoryForSave.close();
}
}
Вот как вызывается хранимая процедура:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116.
@Override
public Object exec_sql_proc(ExecParameters execParameters,Connection externalConnection) {
HashMap<Class, Object> hm = execParameters.getExecParameters();
ResultSet cursor;
ArrayList strout = new ArrayList();
Boolean boolout = null;
// Смотрим на входные параметры и принимаем решение о том, стоит ли что-то делать.
boolean valid_parameters = true;
// Проверяем наличие обязательных параметров.
if (!(hm.containsKey(FunctionToCall.class))
&& !(hm.containsKey(InputParameters.class))
&& !(hm.containsKey(InputParametersTypes.class))
&& !(hm.containsKey(OutputParameters.class))
&& !(hm.containsKey(OutputParametersTypes.class))
&& !(hm.containsKey(FunctionOutputType.class))) {
return null;
}
// Если параметры у нас неправильные, то возвращаем null!
if (!valid_parameters) {
return null;
}
try {
String arguments = "()";
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().size() > 0) {
arguments = "(";
for (int i = 0; i < ((InputParameters) hm.get(InputParameters.class)).getInputParameters().size(); i++) {
arguments = arguments + "?,";
}
arguments = arguments.substring(0, arguments.length() - 1) + ")";
}
Connection connection;
if(externalConnection==null){
connection = ds.getConnection();
}
else{
connection=externalConnection;
}
CallableStatement callableStatement = connection.prepareCall("begin ? := " + ((FunctionToCall) hm.get(FunctionToCall.class)).getFunction() + arguments + "; end;");
//callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
if (((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType() != OracleTypes.BOOLEAN) {
callableStatement.registerOutParameter(1, ((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType());
} else {
callableStatement.registerOutParameter(1, OracleTypes.NUMBER);
}
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().size() > 0) {
for (int i = 0; i < ((InputParameters) hm.get(InputParameters.class)).getInputParameters().size(); i++) {
// Тут можно перечислить типы:
if (((InputParametersTypes) hm.get(InputParametersTypes.class)).getInputParametersTypes().get(i).equals(java.lang.String.class)) {
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i) instanceof java.lang.String) {
callableStatement.setString(2 + i, (String) ((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i).toString());
}
} else if (((InputParametersTypes) hm.get(InputParametersTypes.class)).getInputParametersTypes().get(i).equals(java.lang.Integer.class)) {
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i) instanceof java.lang.Integer) {
callableStatement.setBigDecimal(2 + i, BigDecimal.valueOf((long) (((Integer) ((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i)).intValue())));
}
} else if (((InputParametersTypes) hm.get(InputParametersTypes.class)).getInputParametersTypes().get(i).equals(BigDecimal.class)) {
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i) instanceof BigDecimal) {
callableStatement.setBigDecimal(2 + i, (BigDecimal) ((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i));
}
} else if (((InputParametersTypes) hm.get(InputParametersTypes.class)).getInputParametersTypes().get(i).equals(java.lang.Boolean.class)) {
if (((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i) instanceof java.lang.Boolean) {
callableStatement.setBoolean(2 + i, (Boolean) ((InputParameters) hm.get(InputParameters.class)).getInputParameters().get(i));
}
}
}
}
OracleCallableStatement ocs = callableStatement.unwrap(oracle.jdbc.OracleCallableStatement.class);
boolean bb = callableStatement.execute();
if (((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType() == OracleTypes.CURSOR) {
cursor = ocs.getCursor(1);
while (cursor.next()) {
HashMap<String, Object> strout_ = new HashMap<String, Object>();
for (int i = 0; i < ((OutputParameters) hm.get(OutputParameters.class)).getOutputParameters().size(); i++) {
if (((OutputParametersTypes) hm.get(OutputParametersTypes.class)).getOutputParametersTypes().get(i).equals(java.lang.String.class)) {
strout_.put((String) ((OutputParameters) hm.get(OutputParameters.class)).getOutputParameters().get(i), cursor.getString((String) ((OutputParameters) hm.get(OutputParameters.class)).getOutputParameters().get(i)));
} else if (((OutputParametersTypes) hm.get(OutputParametersTypes.class)).getOutputParametersTypes().get(i).equals(BigDecimal.class)) {
strout_.put((String) ((OutputParameters) hm.get(OutputParameters.class)).getOutputParameters().get(i), cursor.getBigDecimal((String) ((OutputParameters) hm.get(OutputParameters.class)).getOutputParameters().get(i)));
}
}
strout.add(strout_);
}
cursor.close();
} else if (((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType() == OracleTypes.BOOLEAN) {
boolout = ocs.getBoolean(1);
}
ocs.close();
callableStatement.close();
if(externalConnection==null){
connection.close();
}
} catch (Exception e) {
errors = e.getMessage();
return null;
}
if (((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType() == OracleTypes.CURSOR) {
return strout;
}
if (((FunctionOutputType) hm.get(FunctionOutputType.class)).getOracleType() == OracleTypes.BOOLEAN) {
return boolout;
}
return null;
}
А вот самое главное persistence.xml:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
<persistence-unit name="ServerPUsave" transaction-type="RESOURCE_LOCAL">
..................................
<class>com.imc.medfin.server.dao.factory.OracleFactory.bean.DebugTest</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<validation-mode>NONE</validation-mode>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@pgserver1:1521:XE"/>
<property name="javax.persistence.jdbc.user" value="..."/>
<property name="javax.persistence.jdbc.password" value="..."/>
<property name="eclipselink.jdbc.connections.initial" value="1"/>
<property name="eclipselink.jdbc.connections.min" value="1"/>
<property name="eclipselink.jdbc.connections.max" value="4"/>
</properties>
</persistence-unit>
Почему-то когда параметры:
1. 2.
<property name="eclipselink.jdbc.connections.initial" value="1"/>
<property name="eclipselink.jdbc.connections.min" value="1"/>
Были = 0, то:
1. 2. 3. 4.
EntityManagerImpl d=(EntityManagerImpl)ems.getDelegate();
ServerSession s=d.getServerSession();
Accessor a=s.getAccessor();
Connection con=a.getConnection();
con был = NULL!
Почему это так для меня загадка. Не знаю. Сделал эти параметры = 1 и всё заработало.
Хранимая процедура записала данные в:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
--------------------------------------------------------
-- DDL for Table DEBUG_TEST
--------------------------------------------------------
CREATE GLOBAL TEMPORARY TABLE "DEBUG_TEST"
( "ID" NUMBER(10,0),
"DATA" VARCHAR2(128 BYTE)
) ON COMMIT PRESERVE ROWS ;
--------------------------------------------------------
-- DDL for Index DEBUG_TEST_PK
--------------------------------------------------------
CREATE UNIQUE INDEX "DEBUG_TEST_PK" ON "DEBUG_TEST" ("ID")
;
--------------------------------------------------------
-- Constraints for Table DEBUG_TEST
--------------------------------------------------------
ALTER TABLE "DEBUG_TEST" MODIFY ("ID" NOT NULL ENABLE);
ALTER TABLE "DEBUG_TEST" ADD CONSTRAINT "DEBUG_TEST_PK" PRIMARY KEY ("ID")
;
А Java, точнее GlassFish прочитал эти данные в рамках одного соединения.
|
|
|