2011-06-27 40 views
21

Tôi đang sử dụng Apache Commons DBCP (commons-dbcp.jar) Hồ bơi kết nối.

Khi tôi nhận được kết nối từ hồ bơi, nó được gói trong lớp org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.

Yêu cầu của tôi là chuyển một chuỗi các chuỗi tới pl/sql được lưu trữ trong Oracle.

Đây là những gì tôi đang làm trong đoạn mã sau:

Connection dbConn = ConnectionManager.ds.getConnection(); 
//The above statement returns me an connection wrapped in the class 
//org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper. 

org.apache.commons.dbcp.DelegatingConnection del = new org.apache.commons.dbcp.DelegatingConnection(dbConn.getConnection()); 
con = del.getInnermostDelegate(); 

cs = con.prepareCall("call SP_NAME(?,?,?,?)"); 
oracle.sql.ArrayDescriptor arDesc= oracle.sql.ArrayDescriptor.createDescriptor("ARRAY_NAME", (OracleConnection) con); 

CallableStatement c_stmt = conn.prepareCall("begin update_message_ids_ota 
(:x); end;"); 
c_stmt.setArray(1, array_to_pass); 
c_stmt.execute(); 

On thi đoạn mã trên, tôi nhận được ngoại lệ sau đây:

java.lang.ClassCastException: org.apache .commons.dbcp.PoolingDataSource $ PoolGuardConnectionWrapper không thể truyền tới oracle.jdbc.OracleConnection tại oracle.sql.ArrayDescriptor.createDescriptor

Tôi đã cố gắng tìm ra giải pháp về vấn đề này trong hầu hết các trang web và diễn đàn, nhưng không thể có được câu trả lời hay giải pháp thỏa mãn.

+0

Tại sao bạn lại quấn 'dbConn' chỉ để mở lại nó? Điều gì xảy ra nếu bạn gọi 'getInnermostDelegate' trực tiếp trên' dbConn'? – Thilo

Trả lời

22

Theo mặc định, DBCP không cho phép truy cập vào cá thể kết nối cơ sở dữ liệu "thực" bên dưới, vì vậy bạn không thể truy cập lớp Oracle.

Khi configuring hồ bơi, bạn có thể đặt

accessToUnderlyingConnectionAllowed = true 

và sau đó nó hoạt động.

Mặc định là sai, đó là một hoạt động nguy hiểm tiềm tàng và các chương trình hoạt động sai có thể làm những điều có hại. (đóng phần dưới hoặc tiếp tục sử dụng khi kết nối được bảo vệ đã đóng) Hãy cẩn thận và chỉ sử dụng khi bạn cần truy cập trực tiếp vào các phần mở rộng cụ thể của trình điều khiển

GHI CHÚ: Không đóng kết nối bên dưới, chỉ kết nối ban đầu.

+0

Tôi có các thông số sau được sử dụng trong chi tiết tài nguyên, vẫn không hoạt động. initialSize = "5" maxActive = "5" minidle = "5" \t \t maxIdle = "5" \t maxWait = "20000" removeAbandoned = "true" removeAbandonedTimeout = "60" \t \t maxIdleTime =" 3000 "accessToUnderlyingConnectionAllowed =" true " – Prodigy

+0

Điều này đã giúp tôi rất nhiều, cảm ơn bạn! – mtrovo

+0

@Prodigy Bạn có giải pháp không? tôi đang đối mặt với cùng một vấn đề. – Shibankar

2

Tôi positing này ở đây để đảm bảo bất cứ ai khác tìm kiếm những lời khuyên biết về giải pháp cuối cùng như sau:

Nếu bạn buộc phải sử dụng phiên bản không kèm của người quản lý bền bỉ (vì một kho lưu trữ cũ vẫn sử dụng cấu trúc đó không tương thích với bố cục được nhóm), dưới đây là những gì bạn có thể làm, giải pháp khá đơn giản:

Tải xuống nguồn cho Jackrabbit Core (bạn có thể lấy chúng từ trang web Jackrabbit) Mở Lớp OraclePersistenceManager và tìm dòng mã sau đây:

Object blob = createTemporary.invoke(null, 
       new Object[]{con, Boolean.FALSE, durationSessionConstant}); 

(Khoảng dòng 377 - cũng có thể kiểm tra StackTrace để tham khảo)

ConnectionFactory chứa một phương thức tĩnh cho phép để unwrap một kết nối đó là chính xác những gì bạn cần:

Object blob = createTemporary.invoke(null, 
       new Object[]{org.apache.jackrabbit.core.util.db.ConnectionFactory 
         .unwrap(con), Boolean.FALSE, durationSessionConstant}); 

Bạn sẽ cần Maven 2+ để biên dịch các nguồn, tôi đã làm điều đó và không có vấn đề phụ thuộc, lưu ý rằng tôi đã biên dịch phiên bản 2.2.10 của Jackrabbit.

Tôi cũng chắc chắn để đăng nhập một lỗi đối với Jackrabbit 2.2.11 (phiên bản hiện tại mà vẫn có vấn đề): https://issues.apache.org/jira/browse/JCR-3262

Hope this helps!

4

Hmmm , Tôi đã đáp ứng được giải pháp giống như bạn. Tôi nghĩ có hai vị trí bạn cần đề cập đến. 1.Config Thiết lập nhóm kết nối accessToUnderlyingConnectionAllowed = "true"; 2.Mỗi cơn ác mộng liên quan đến dự án nguồn mở. Các conceration terrable. Trong trường hợp này, đó là

org.apache.commons.dbcp.DelegatingConnection 

không bằng

org.apache.tomcat.dbcp.dbcp.DelegatingConnection 

trong khi mặc định apache chung dbcp.jar, bạn sẽ không bao giờ tìm ra theo Class.But chỉ lớp là chìa khóa . Vì vậy, chúng ta phải tìm lớp ở đâu đó. Cuối cùng tôi tìm thấy gói tomcat-dbcp .jar. Bạn có thể lấy nó từ http://www.docjar.com/ Sau

import org.apache.tomcat.dbcp.dbcp.DelegatingConnection 

, bạn có thể buộc dàn diễn viên bạn dbConn và nhận được kết nối cơ bản

oracle.jdbc.driver.OracleConnection delConn = 

(oracle.jdbc.driver.OracleConnection) 

((org.apache.tomcat.dbcp.dbcp.DelegatingConnection)c_stmt.getConnection()).getDelegate(); 

Sau đó, chúng ta có thể sử dụng delConn để có được những ArrayDescriptor Ghi một điều, trong đó , chúng tôi không cần số

org.apache.commons.dbcp.DelegatingConnection Class 

Thật lạ lùng, nhưng thực tế là đúng.

+0

omg, đây là câu trả lời tôi cần, rất khó hiểu rằng tomcat đã thay đổi đường dẫn ... – Reimius

5

Nhìn bài này tôi có thể nhận được OracleConnection với mã này:

DataSource ds1 = // get the org.apache.commons.dbcp.PoolingDataSource 
org.apache.tomcat.dbcp.dbcp.DelegatingConnection del = new org.apache.tomcat.dbcp.dbcp.DelegatingConnection(cds1.getConnection()); 
OracleConnection con = (OracleConnection) del.getInnermostDelegate(); 

nhớ commons-DBCP-1.4.jar neet được trong đường dẫn lớp

1

Chúng tôi sử dụng mảng trong các cuộc gọi của chúng tôi để lưu trữ procs oracle và sử dụng api độc quyền oracle để xây dựng mảng. Kiểm tra nhỏ này đã khắc phục sự cố cho chúng tôi khi sử dụng chức năng từ các ứng dụng độc lập sử dụng commons-dbcp.

if (conn instanceof org.apache.commons.dbcp.DelegatingConnection) 
    { 
     log.debug("detected apache commons dbcp datasource"); 
     conn = ((org.apache.commons.dbcp.DelegatingConnection) conn).getInnermostDelegate(); 
    } 

Mặc dù vậy, bạn sẽ cần commons-dbcp trong classpath/dependecies.

<dependency> 
     <groupId>commons-dbcp</groupId> 
     <artifactId>commons-dbcp</artifactId> 
     <version>1.4</version> 
     <scope>provided</scope> 
    </dependency> 
16

Nếu bạn đang sử dụng một Java 6 compliant JDBC kết nối, bạn có thể sử dụng mã như sau:

OracleConnection oracleConnection = null; 
try { 
    if (connection.isWrapperFor(OracleConnection.class)) { 
     oracleConnection = connection.unwrap(OracleConnection.class); 
    } 
} catch (SQLException ex) { 
    // do something 
} 
return oracleConnection; 

Từ thời điểm này trở đi, sử dụng oracleConnection thay vì bản gốc connection.

Xem http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.html

+0

Nó không có giá trị gì ở đây bạn muốn nhập giao diện OracleConnection * * vào oracle.jdbc thay vì thực thi cụ thể với cùng tên. – Andrew

1

Tôi đã gặp phải vấn đề tương tự. Chúng tôi đã sử dụng mùa xuân và nó có một lớp được gọi là NativeJdbcExtractor. Nó có nhiều triển khai và phần sau hoạt động với TomCat. Có các triển khai cụ thể cho Websphere, máy chủ ứng dụng Weblogic.

<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean> 

Trong DAO của bạn, bạn có thể tiêm các hạt và sử dụng các phương pháp sau đây

protected NativeJdbcExtractor jdbcExtractor; 
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection); 
+0

Đây là câu trả lời duy nhất phù hợp với tôi. 'accessToUnderlyingConnectionAllowed' không thay đổi bất cứ điều gì và các câu trả lời khác thêm phụ thuộc rõ ràng vào 'commons-dbcp' không được chấp nhận. Cảm ơn! –

0

trong định nghĩa ngữ cảnh của bạn thêm bên dưới thẻ để định nghĩa xml hiện tại của bạn.

factory="oracle.jdbc.pool.OracleDataSourceFactory 
scope="Shareable" 
type="oracle.jdbc.pool.OracleDataSource" 

.

0

Đối với bất kỳ ai đang tìm kiếm, getDelegate()getInnermostDelegate() cả hai đều trả về NULL trong mã của tôi. Tuy nhiên, từ trình gỡ rối tôi tìm thấy OracleConnection như dưới đây. Chúng tôi sử dụng Spring JdbcTemplate trong suốt ứng dụng, trong đó có nguồn dữ liệu được tiêm. Chúng tôi đang ở trên spring-jdbc-4.1.5.RELEASE.jar và ojdbc6.jar.

Connection conn = getJdbcTemplate().getDataSource().getConnection(); 

OracleConnection oracleConnection = (OracleConnection) conn.getMetaData().getConnection(); 
0

Tôi đang làm việc với tomcat 8.5.8 và đang đối mặt với vấn đề này.
Giải pháp dưới đây hoạt động như sự quyến rũ.


Bộ luật:

Delegating Connection delegate_conn = new Delegating Connection(connection) 
conn = delegate_conn.getInnermostDelegate(); 
oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TABLE_VIEW", conn); 

Giải pháp:

Thêm phụ thuộc cho tomcat-dbcp 8.5.8 và thêm jar cùng trong thư mục lib của tomcat.
Dường như tomcat có các lọ khác nhau cho các phiên bản khác nhau bắt đầu từ 7,0 (tham khảo: https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp).

Hy vọng nó sẽ giúp ai đó.

Các vấn đề liên quan