2012-09-20 7 views
12

Prawie mówi to w tytule. Mam klasy, który wygląda mniej więcej tak:Jak zmapować ciąg do sekwencji DB w 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; } 
} 

Korzystanie z Oracle 11g, kolumna FOO_ID jest VARCHAR2, ale sekwencja SQ_FOO_ID daje NUMBER. Baza danych najwyraźniej jest zadowolona z tego, ale aplikacja musi obsługiwać nie-numeryczne identyfikatory, które mogły zostać wstawione do tej kolumny poza aplikacją.

Biorąc pod uwagę powyższy kod, otrzymuję org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String. Czy istnieje sposób na wykonanie tego mapowania?

Używanie Hibernate 3.6.

Odpowiedz

10

Implementacja niestandardowej klasy IdentifierGenerator; od A 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; 
    } 
} 

opisanie jednostka PK tak:

@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; 
} 

Ze względu na błąd w Eclipse, błąd może być podniesiony, że generator (seq_id) nie jest zdefiniowana w module utrwalania . Ustaw to ostrzeżenie, co następuje:

  1. Wybierz Okno »Preferencje
  2. Rozwiń Java Persistence» JPA »Błędy/ostrzeżenia
  3. Kliknij zapytań i generatory
  4. ustawić Generator niezdefiniowane w jednostce trwałości do: Warning
  5. Kliknij OK, aby zastosować zmiany i zamknąć okno dialogowe
3

To kolejne podejście:

parametr
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(); 
    } 
} 

Sekwencja musi być określona na posesji Id jak w poniższym przykładzie:

@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; 
} 
Powiązane problemy