2011-01-17 3 views
4

Oracle은 VARRAYS 및 NESTED TABLE 데이터 형식을 지원하여 다중 값 특성을 허용합니다. (http://www.orafaq.com/wiki/NESTED_TABLE)최대 절전 모드 및 Oracle VARRAYS/NESTED TABLE

현재 ORM 프레임 워크로 Hibernate 3을 사용하고 있지만 Hibernate를 내 데이터베이스의 중첩 테이블/VARRAY 데이터 유형에 매핑하는 방법을 알 수 없습니다.

나는 Hibernate에서 커스텀 타입을 정의하는 것을 보았다. 성공하지 못했다. (심지어 최대 절전 모드에서 서브 테이블을 훼손하지 않고 필요한 "COLUMN_VALUE"Oracle 키워드를 처리 할 수 ​​있습니까?)

누구나 최대 절전 모드에서 이러한 데이터 유형을 구현하는 방법을 알고 있습니까?

도움 주셔서 감사합니다.

- TBW.

답변

1

나는 틀렸어. 당신이 연구에서 더 나은 대답을 찾길 희망하지만,이 기능은 Hibernate에서 지원되지 않는다. Hibernate는 표준 JDBC를 사용하여 데이터베이스와 통신하며 이러한 기능은 표준의 일부가 아닙니다. 그것들은 Oracle 확장입니다.

1) 자신의 UserType을 구현 :

내가 몇 가지 해결 방법을 생각할 수 말했다. 특정 사용자 유형을 사용하면 데이터베이스에서 제공 한 값을 조작 할 수 있습니다 (또는 데이터베이스로 전송 될 때). 그러나 이것은 오라클이이 값을 java.sql.Types 중 하나로서 제공하는 경우에만 작동합니다. http://download.oracle.com/javase/1.5.0/docs/api/java/sql/Types.html

2) 다른 옵션은 최대 절전 모드 작업자의 사용을 통해 JDBC를 직접 사용하는 것입니다. 이 예제의 노동자를보십시오 : https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/test/java/org/hibernate/test/jdbc/GeneralWorkTest.java

즉, 솔루션을 중점적으로 생각하고 중첩 테이블이 필요한지 다시 평가해야한다고 생각합니다.

+0

예, Hibernate는 모든 벤더 특정 확장을 지원할 수 없습니다. 우리는 DAO 객체를 사용하여 오라클 유형의 상위 레이어를 보호하므로 향후 구현을 변경할 수 있습니다. – xmedeko

3

오라클의 테이블 개수에 대한 최대 절전 모드 사용자 유형. OracleNativeExtractor 여기에 있습니다 : https://community.jboss.org/wiki/MappingOracleXmlTypeToDocument. YOUR_CUSTOM_ARRAY_TYPE 문자열이 귀하의 이름으로 대체됩니다.

import oracle.sql.ARRAY; 
import oracle.sql.ArrayDescriptor; 
import org.apache.commons.lang.ArrayUtils; 
import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 

import java.io.Serializable; 
import java.sql.*; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List;  

public class ArrayUserType 
    implements UserType, Serializable { 

private static final OracleNativeExtractor EXTRACTOR = new OracleNativeExtractor(); 

@Override 
public int[] sqlTypes() { 
    return new int[]{Types.ARRAY}; 
} 

@Override 
public Class returnedClass() { 
    return List.class; 
} 

@Override 
public boolean equals(Object x, Object y) throws HibernateException { 
    if (x == null && y == null) return true; 
    else if (x == null && y != null) return false; 
    else return x.equals(y); 
} 

@Override 
public int hashCode(Object x) throws HibernateException { 
    return x.hashCode(); 
} 

@Override 
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { 
    return Arrays.asList(ArrayUtils.toObject(((ARRAY) rs.getObject(names[0])).getLongArray())); 
} 

@Override 
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { 
    ARRAY array = null; 
    if (value != null) { 
     Connection nativeConn = EXTRACTOR.getNativeConnection(st.getConnection()); 
     ArrayDescriptor descriptor = 
       ArrayDescriptor.createDescriptor("YOUR_CUSTOM_ARRAY_TYPE", nativeConn); 
     array = new ARRAY(descriptor, nativeConn, ((List<Long>) value).toArray(new Long[]{})); 
    } 

    st.setObject(1, array); 
} 

@Override 
public Object deepCopy(Object value) throws HibernateException { 
    if (value == null) return null; 

    return new ArrayList<Long>((List<Long>) value); 
} 

@Override 
public boolean isMutable() { 
    return false; 
} 

public Object assemble(Serializable _cached, Object _owner) 
     throws HibernateException { 
    return _cached; 
} 

public Serializable disassemble(Object _obj) 
     throws HibernateException { 
    return (Serializable) _obj; 
} 

@Override 
public Object replace(Object original, Object target, Object owner) throws HibernateException { 
    return deepCopy(original); 
} 
} 
+0

그게 전부 야? 최대 절전 모드 엔티티에서 이것을 매핑해야합니까? 이 수업을 어떻게 사용합니까? –

+0

예, 엔티티에서이를 매핑해야합니다. hibernate annotation을 사용한다면 @Type (type = "mypackage.ArrayUserType")을 필드에 추가하십시오. –