簡體   English   中英

hibernate中復合鍵的自動生成

[英]Automatic generation of composite key in hibernate

早上好。
我有一個帶有復合主鍵的數據庫表。 這是表的create語句

CREATE COLUMN TABLE "ACQUISTO_EVENTI"(
"COD_PROPOSTA_EVENTO" VARCHAR(100) NOT NULL,
"COD_PROPOSTA" INTEGER CS_INT,
"ID_EVENTO" INTEGER CS_INT,
"TIPO_OPERAZIONE" VARCHAR(100),
    ... others fields...
PRIMARY KEY (
    "COD_PROPOSTA_EVENTO"
)

復合主鍵公式為

COD_PROPOSTA_EVENTO = "COD_PROPOSTA" + _ + "ID_EVENTO"

為了將數據保存在數據庫中,我創建了以下 POJO object

@Entity
@Table(name = "ACQUISTO_EVENTI")
@JsonIgnoreProperties(ignoreUnknown = true)
public class PropostaAcquisto implements Serializable {
    
    private static final long serialVersionUID = -5977779326596870770L;

    public PropostaAcquisto() {
        super();
    }
    
    @Id 
    @Column(name = "COD_PROPOSTA_EVENTO", length=100)
    private String codPropostaEventoPrimaryKey;
    
    @Column(name = "COD_PROPOSTA")
    private Integer codProposta;        
    
    @Column(name = "ID_EVENTO")
    private Integer idEvento;   
    
    @Column(name = "TIPO_OPERAZIONE", length=100)
    private String tipoOperazione;
    
        ... others fields...

    public Integer getCodProposta() {
        return codProposta;
    }

    public void setCodProposta(Integer codProposta) {
        this.codProposta = codProposta;
    }

    public Integer getIdEvento() {
        return idEvento;
    }

    public void setIdEvento(Integer idEvento) {
        this.idEvento = idEvento;
    }
    
    public String getCodPropostaEventoPrimaryKey() {
        return codProposta + "_" + idEvento;
    }

    public void setCodPropostaEventoPrimaryKey(String codPropostaEventoPrimaryKey) {
        this.codPropostaEventoPrimaryKey = codProposta + "_" + idEvento;
    }
    
    public String getTipoOperazione() {
        return tipoOperazione;
    }

    public void setTipoOperazione(String tipoOperazione) {
        this.tipoOperazione = tipoOperazione;
    }

            ... others getter and setters...
}

當我嘗試使用以下代碼保存 object

   public Object saveOrUpdate() {
        PropostaAcquisto propostaAcquisto = new PropostaAcquisto();
        propostaAcquisto.setCodProposta(1);
        propostaAcquisto.setIdEvento(1);

        Transaction transaction = null;
        try {
            if (session == null || ! session.isOpen()) {
                session = HibernateFactory.getSessionFactory().openSession();
            } 
            transaction = session.beginTransaction();
            session.saveOrUpdate(obj);
            transaction.commit();
        } catch (JDBCException e) {
            System.out.println("Dettaglio errore >>> "+e.getSQLException().getMessage());
            obj = null;
        } finally {
            if (session != null) {
                session.close();
            } 
        }
        return obj;
    }

我收到以下錯誤

Exception in thread "main" org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): PropostaAcquisto

有一種方法可以使用 Hibernate 自動生成主鍵,而無需直接調用

propostaAcquisto.setCodPropostaEventoPrimaryKey()

在保存 object 之前?
有人可以為我提供一些示例或文檔鏈接嗎?
謝謝
問候

對於 Hibernate 5.x

您可能可以使用@PrePersist

@Entity
@Table(name = "ACQUISTO_EVENTI")
@JsonIgnoreProperties(ignoreUnknown = true)
public class PropostaAcquisto implements Serializable {

    @PrePersist
    public void createKey() {
        this.codPropostaEventoPrimaryKey = this.codProposta + "_" + this.eventoId;
    }

}

有關 JPA 回調的更多信息,請參閱 Hibernate ORM 文檔。

對於 Hibernate ORM 4.3.x

如果您使用的是舊版本的 Hibernate ORM,您可能可以在EventType.PERSIST上實現相同的注冊事件監聽器:

public class MyIntegrator implements org.hibernate.integrator.spi.Integrator {

    public void integrate(
            Configuration configuration,
            SessionFactoryImplementor sessionFactory,
            SessionFactoryServiceRegistry serviceRegistry) {

        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

        // If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an
        // implementation of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
        eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy );

        // This form adds the specified listener(s) to the beginning of the listener chain
        eventListenerRegistry.prependListeners( EventType.PERSIST, new CreatePKBeforePersist() );
}

其中CreatePKBeforePersist是實現 PersistEventListener 的PersistEventListener

因為您無法將偵聽器綁定到特定實體,所以您必須在應用更改之前檢查 object:

public class CreatePKBeforePersist implements PersistEventListener {

    public void onPersist(PersistEvent event) throws HibernateException {
        if (event.getObject() instanceof PropostaAcquisto) {
            PropostaAcquisto pa = (PropostaAcquisto) event.getObject();
            pa.createKey();
        }
    }

    ...
}

本文介紹了如何注冊集成商

在以下位置添加文本文件:

/META-INF/services/org.hibernate.integrator.spi.Integrator

該文件將僅包含 class 的全名:

org.project.MyIntegrator

您可以查看java.util.ServiceLoader JavaDocs 以獲取文件中可能包含的內容的完整說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM