2012-09-20 33 views
12

Khá nhiều khi nói nó trong tiêu đề. Tôi có một lớp học mà trông giống như sau:Làm thế nào để ánh xạ chuỗi thành chuỗi DB trong Hibernate

@Entity 
@Table(name="FOO") 
public class Foo { 

    private String theId; 

    @Id 
    @Column(name = "FOO_ID") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fooIdSeq") 
    @SequenceGenerator(name = "fooIdSeq", sequenceName = "SQ_FOO_ID", allocationSize = 10) 
    public String getTheId() { return theId; } 

    public String setTheId(String theId) { this.theId = theId; } 
} 

Sử dụng Oracle 11g, cột FOO_ID là một VARCHAR2, nhưng chuỗi SQ_FOO_ID mang lại một NUMBER. Cơ sở dữ liệu dường như hài lòng với điều này, nhưng ứng dụng cần có khả năng hỗ trợ các ID không phải là số có thể đã được chèn vào cột này bên ngoài ứng dụng.

Xem xét mã ở trên, tôi nhận được org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String. Có cách nào để thực hiện ánh xạ này không?

Sử dụng Hibernate 3.6.

Trả lời

10

Triển khai lớp IdentifierGenerator tùy chỉnh; từ một blog post:

import java.io.Serializable; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

import org.hibernate.HibernateException; 
import org.hibernate.engine.spi.SessionImplementor; 
import org.hibernate.id.IdentifierGenerator; 

public class StringKeyGenerator implements IdentifierGenerator { 

    @Override 
    public Serializable generate(SessionImplementor session, Object collection) throws HibernateException { 
     Connection connection = session.connection(); 
     PreparedStatement ps = null; 
     String result = ""; 

     try { 
      // Oracle-specific code to query a sequence 
      ps = connection.prepareStatement("SELECT TABLE_SEQ.nextval AS TABLE_PK FROM dual"); 
      ResultSet rs = ps.executeQuery(); 

      if (rs.next()) { 
       int pk = rs.getInt("TABLE_PK"); 

       // Convert to a String 
       result = Integer.toString(pk); 
      } 
     } catch (SQLException e) { 
      throw new HibernateException("Unable to generate Primary Key"); 
     } finally { 
      if (ps != null) { 
       try { 
        ps.close(); 
       } catch (SQLException e) { 
        throw new HibernateException("Unable to close prepared statement."); 
       } 
      } 
     } 

     return result; 
    } 
} 

Chú thích đơn vị PK như thế này:

@Id 
@GenericGenerator(name="seq_id", strategy="my.package.StringKeyGenerator") 
@GeneratedValue(generator="seq_id") 
@Column(name = "TABLE_PK", unique = true, nullable = false, length = 20) 
public String getId() { 
    return this.id; 
} 

Do một lỗi trong Eclipse, một lỗi có thể được nâng lên rằng máy phát điện (seq_id) không được định nghĩa trong đơn vị bền vững . Thiết lập này để cảnh báo như sau:

  1. Chọn Window »Preferences
  2. Mở rộng Java Persistence» JPA »lỗi/cảnh báo
  3. Bấm Queries và máy phát
  4. Đặt Generator là không được xác định trong đơn vị liên tục tới: Warning
  5. Nhấp vào OK để áp dụng thay đổi và đóng hộp thoại
3

Đây là cách tiếp cận khác:

tham số
import java.io.Serializable; 

import org.hibernate.engine.spi.SessionImplementor; 
import org.hibernate.id.IdentifierGeneratorHelper.BigDecimalHolder; 
import org.hibernate.id.IntegralDataTypeHolder; 
import org.hibernate.id.SequenceGenerator; 

public class StringSequenceGenerator extends SequenceGenerator { 
    @Override 
    public Serializable generate(SessionImplementor session, Object obj) { 
     return super.generate(session, obj).toString(); 
    } 

    protected IntegralDataTypeHolder buildHolder() { 
     return new BigDecimalHolder(); 
    } 
} 

Trình tự phải được xác định trên tài sản id như trong ví dụ sau:

@Id 
@GenericGenerator(name = "STRING_SEQUENCE_GENERATOR", strategy = "mypackage.StringSequenceGenerator", parameters = { @Parameter(name = "sequence", value = "MY_SEQUENCE_NAME") }) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "STRING_SEQUENCE_GENERATOR") 
@Column(name = "MY_ID") 
public String getMyId() { 
    return this.myId; 
} 
Các vấn đề liên quan