簡體   English   中英

JPA / Hibernate在沒有任何命令的情況下在表中進行更新

[英]JPA/Hibernate doing update in table without any command

好吧,我使用JSF + Hibernate / JPA,我有以下代碼:

  public void loadAddressByZipCode(ActionEvent event){
    Address address = boDefault.findByNamedQuery(Address.FindByZipCode, 'zipCode', bean.getAddress().getZipCode());

    if (address == null){
      //This zip code not exists in db
   }else{
      bean.setAddress(address);
   }
  }

上面的方法在XHTML頁面的inputText組件中的每個“ onBlur”中都被調用,該inputText具有如下屬性值:“#{addressMB.bean.address.zipCode}”

因此,當用戶(在XHTML頁面中)鍵入新的郵政編碼時,將在“ bean.getAddress()。setZipCode()”中設置此值,然后在數據庫中搜索該值。 但是調試我的應用程序后,我發現當我執行“ bean.getAddress()。getZipCode()”時,Hibernate在我的數據庫中啟動了一個“更新地址集...”。 我該如何防止這種情況發生,為什么呢?

編輯1:這是我實現的真正方法

public void carregarLogradouroByCep(AjaxBehaviorEvent event) {
        List listReturn = getBoPadrao().findByNamedQuery(
                Logradouro.FIND_BY_CEP,
                new NamedParams("cep", bean.getLogradouro().getCep()));

        if (listReturn.size() > 0) {
            Logradouro logradouro = (Logradouro) listReturn.get(0);
            bean.setLogradouro(logradouro);
        }else{
            bean.setLogradouro(new Logradouro());
        }
    }

這是我的onblur事件組件:

<p:inputText value="#{enderecoMB.bean.logradouro.cep}" id="cep"
                        required="true" requiredMessage="O CEP é obrigatório">
                        <p:ajax event="blur"
                            listener="#{enderecoMB.carregarLogradouroByCep}"
                            update=":formManterEndereco:logradouro, :formManterEndereco:cidade, :formManterEndereco:estado, 
                        :formManterEndereco:bairro" />
                    </p:inputText>

我有一個“ BasicDAOImpl”,可以在數據庫中進行所有操作,因此嘗試在我的entityManager中執行此操作:

@PostConstruct
    private void init(){        
        entityManager.setFlushMode(FlushModeType.COMMIT);
    }

但是“自動更新”繼續。

編輯2:我的FIND_BY_CEP查詢

"SELECT c FROM Endereco c JOIN FETCH c.tipoEndereco JOIN FETCH c.logradouro"

EDit 3:我的實體

Endereco.java

@Entity
@NamedQueries(value = { @NamedQuery(name = "Endereco.findAllCompleto", query = "SELECT c FROM Endereco c "
        + "JOIN FETCH c.tipoEndereco " + "JOIN FETCH c.logradouro") })
@Table(name = "endereco")
public class Endereco extends AbstractBean {



    /**
     * 
     */
    private static final long serialVersionUID = 5239354646908722819L;

    public Endereco(){
        logradouro = new Logradouro();
    }

    @Transient
    public static final String FIND_ALL_COMPLETO = "Endereco.findAllCompleto";

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_tipo_endereco")
    private TipoEndereco tipoEndereco;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinColumn(name = "id_logradouro")
    private Logradouro logradouro;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_pessoa")
    private Pessoa pessoa;

    @Column
    private String numero;

    @Column
    private String complemento;

    public Logradouro getLogradouro() {
        return logradouro;
    }

    public void setLogradouro(Logradouro logradouro) {
        this.logradouro = logradouro;
    }

    public TipoEndereco getTipoEndereco() {
        return tipoEndereco;
    }

    public void setTipoEndereco(TipoEndereco tipoEndereco) {
        this.tipoEndereco = tipoEndereco;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }

    public String getComplemento() {
        return complemento;
    }

    public void setComplemento(String complemento) {
        this.complemento = complemento;
    }

    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }



}

Logradouro.java

@Entity
@NamedQueries(value = { @NamedQuery(name = "Logradouro.findByCep", query = "SELECT c FROM Logradouro c "
        + "JOIN FETCH c.bairro "
        + "JOIN FETCH c.cidade "
        + "WHERE c.cep = :cep "
        + "ORDER BY c.logradouro") })
@Table(name = "logradouro")
public class Logradouro extends AbstractBean {

    public Logradouro(){
        this.cidade = new Cidade();
        this.bairro = new Bairro();
    }

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Transient
    public static final String FIND_BY_CEP = "Logradouro.findByCep";

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinColumn(name = "id_cidade")
    private Cidade cidade;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinColumn(name = "id_bairro")
    private Bairro bairro;

    @Column
    private String cep;

    @Column
    private String logradouro;

    public Cidade getCidade() {
        return cidade;
    }

    public void setCidade(Cidade cidade) {
        this.cidade = cidade;
    }

    public Bairro getBairro() {
        return bairro;
    }

    public void setBairro(Bairro bairro) {
        this.bairro = bairro;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public String getLogradouro() {
        return logradouro;
    }

    public void setLogradouro(String logradouro) {
        this.logradouro = logradouro;
    }
}

默認情況下,Hibernate使用entitymanager來自動處理您的實體。 您的bean就是這樣的一個實體,因此只要實體管理器感覺到需要刷新數據庫的時候,它就會這樣做。 如果要手動沖洗,則需要查看這種構造:

entityManager.setFlushMode(javax.persistence.FlushModeType.MANUAL);

我認為您濫用了Hibernate。 ORM的主要思想是允許您編寫代碼,而忽略了將某些內容存入數據庫的事實。 您的域模型必須完全可測試,沒有任何數據庫。 ORM不是用關系數據庫管理的抽象,而是您的對象模型的抽象。 如果需要顯式地執行insertupdates ,則最好使用一些活動記錄實現或查看MyBatis類的輕量級映射器。

以及為什么要阻止數據庫更新? 財產變了吧? 因此,讓Hibernate決定是否以及何時將其新值寫入數據庫。

暫無
暫無

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

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