JPA没有合并,也没有冲洗我的实体

时间:2014-10-01 19:59:59

标签: java spring hibernate jpa spring-transactions

我遇到了一个问题,我的事务由Spring Tx控制,当我进行合并和刷新后,我的实现不打印命令,而且Spring Tx也没有提交它们。

按照我的代码:

@Named
@Transactional(propagation = Propagation.MANDATORY, readOnly = false)
class AverbacaoDAOImpl extends AbstractDAOImpl<Averbacao, Long> implements AverbacaoDAO{

    private List<Averbacao> atualizarAverbacoes(final List<Averbacao> averbacoes, final EtapaAverbacao etapa) {

        int counter = 0;
        for(Averbacao averbacao : averbacoes) {
            averbacao.setEtapa(etapa);
            atualizar(averbacao);
            counter += 1; 
    }

        entityManager.flush();
        LOGGER.debug("Atualizado {} averbacoes para a etapa {}", counter, etapa);
        return averbacoes;
    }

}

private atualizar(Averbacao averbacao) {
    entityManager.merge(averbacao);
}

列表中的每个对象都由JPA管理(或者我认为它们是

关注日志:

Spring Transaction / Hibernate:

08:37:06,102 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener]           Processing flush-time cascades
08:37:07,576 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Dirty checking collections
08:37:08,703 DEBUG [BilhetagemProcessManagerExecutor-1hread] [Collections] Collection found: [br.com.company.bilhetagem.brms.model.Proposta.propostaTaxaAplicaveis#35340], was: [br.com.company.bilhetagem.brms.model.Proposta.propostaTaxaAplicaveis#35340] (initialized)
08:37:08,706 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 0 deletions to 26047 objects
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] Listing entities:
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] br.com.company.bilhetagem.brms.model.tarifas.TipoTarifaPercentual{percentualMultiplicador=1.0, tipo=OCD}
08:37:08,713 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] More......

Averbacao

@Entity
@Table(name = "TBIL_RELAC_AVERB_PROPT", schema = "BILHET")
@SecondaryTable(name = "TBIL_AVERBACAO", schema = "BILHET", pkJoinColumns = {        @PrimaryKeyJoinColumn(name = "SEQ_NUMER_AVB") })
public final class Averbacao implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = -3229114271975034004L;

@Id
@Column(name = "SEQ_NUMER_AVB")
private long numeroAverbacao;

@ManyToOne(optional = false, targetEntity = Proposta.class)
@JoinColumn(name = "SEQ_NUMER_PRS", nullable = false)
private Proposta proposta;

@Column(name = "VLR_IS", scale = 15, precision = 2, nullable = true)
private Double valorIS;

@ManyToOne(optional = false)
@JoinColumn(name = "CTL_LOCAL_ORI", nullable = false, table = "TBIL_AVERBACAO")
private Localidade origem;

@ManyToOne(optional = false)
@JoinColumn(name = "CTL_LOCAL_DES", nullable = false, table = "TBIL_AVERBACAO")
private Localidade destino;

@ManyToOne(optional = true)
@JoinColumn(name = "CTL_LOCAL_FIM", nullable = true, table = "TBIL_AVERBACAO")
private Localidade destinoFinal;

@Column(name = "DHR_EMBAR", nullable = false, table = "TBIL_AVERBACAO")
@Temporal(TemporalType.DATE)
private Date dataEmbarque;

@Column(name = "IDT_CARGA_DSC", nullable = false, table = "TBIL_AVERBACAO")
private char tipoCargaDescarga;

@Column(name = "IDT_VEICU", nullable = false, table = "TBIL_AVERBACAO")
private String tipoVeiculo;

@Column(name = "STA_AVARI", nullable = false, table = "TBIL_AVERBACAO")
private char indicadorAvaria;

@Column(name = "STA_FLUVI", nullable = false, table = "TBIL_AVERBACAO")
private char indicadorTrechoFluvial;

@Column(name = "NUM_ETAPA_AVB", nullable = false, table = "TBIL_AVERBACAO")
@Type(type = "br.com.company.bilhetagem.brms.dao.jpa.types.EtapaAverbacaoUserType")
private EtapaAverbacao etapa;

public Averbacao() {

}

public Averbacao(final Proposta proposta) {
    this.proposta = proposta;
}

@Transient
public AverbacaoPropostaKey getAverbacaoPropostaKey() {
    final long numeroProposta = 
            this.proposta == null ? 0 : this.proposta.getNumeroProposta();

    return new AverbacaoPropostaKey(this.numeroAverbacao, numeroProposta);
}

public Date getDataEmbarque() {
    return new DateTime(dataEmbarque).toDate();
}

public Localidade getDestino() {
    return destino;
}

public long getNumeroAverbacao() {
    return numeroAverbacao;
}

public Localidade getOrigem() {
    return origem;
}

public Proposta getProposta() {
    return proposta;
}

public Double getValorIS() {
    return valorIS;
}

public char getTipoCargaDescarga() {
    return tipoCargaDescarga;
}

public String getTipoVeiculo() {
    return tipoVeiculo;
}

public char getIndicadorAvaria() {
    return indicadorAvaria;
}

public char getIndicadorTrechoFluvial() {
    return indicadorTrechoFluvial;
}

public Localidade getDestinoFinal() {
    return destinoFinal;
}

public final EtapaAverbacao getEtapa() {
    return etapa;
}

public final void setEtapa(EtapaAverbacao etapa) {
    this.etapa = etapa;
}

@Override
public String toString() {
    return toStringHelper(this).addValue(this.numeroAverbacao)
            .add("Proposta", this.proposta).add("Origem", this.origem)
            .add("Destino", this.destino).addValue(this.dataEmbarque)
            .addValue(this.valorIS).toString();
}

@Override
public int hashCode() {
    return Objects.hashCode(this.dataEmbarque, this.destino,
            this.numeroAverbacao, this.origem, this.proposta, this.valorIS,
            this.tipoCargaDescarga, this.indicadorAvaria,
            this.indicadorTrechoFluvial, this.destinoFinal);
}

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }

    if (obj == this) {
        return true;
    }

    if (obj.getClass() != getClass()) {
        return false;
    }

    final Averbacao that = (Averbacao) obj;

    return equal(this.numeroAverbacao, that.getNumeroAverbacao())
            && equal(this.destino, that.getDestino())
            && equal(this.origem, that.getOrigem())
            && equal(this.proposta, that.getProposta());
}

}

EtapaAverbacao

public enum EtapaAverbacao implements Serializable, PersistentEnum {
NAO_PROCESSADO(1),
PROCESSANDO(2),
PROCESSADO(3);

private int id;

private EtapaAverbacao(final int id) {
    this.id = id;
}

@Override
public int getId() {
    return this.id;
}

}

public abstract class AbstractPersistentEnumUserType实现UserType {

public AbstractPersistentEnumUserType() {

}

public static List<Integer> toIdList(final List<? extends PersistentEnum> enumList) {
    final List<Integer> ids = new ArrayList<Integer>();

    if(enumList == null) {
        return ids;
    }

    for(PersistentEnum e : enumList) {
        ids.add(e.getId());
    }

    return ids;
}

public static List<Integer> toIdList(final PersistentEnum[] enumList) {
    return toIdList(Arrays.asList(enumList));
}

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

@Override
public abstract Class<T> returnedClass();

@Override
public final boolean equals(Object obj1, Object obj2) {
    if(obj1 == null) {
        return false;
    }

    return obj1.equals(obj2);
}

@Override
public final int hashCode(Object obj) {
    return obj == null ? 0 : obj.hashCode();
}

@Override
public final Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException {
    if (rs.wasNull()) {
        return null;
    }

    for (PersistentEnum value : returnedClass().getEnumConstants()) {
        final int id = rs.getInt(names[0]);

        if (id == value.getId()) {
            return value;
        }
    }

    throw new IllegalStateException("Unknown " + returnedClass().getSimpleName() + " id");
}

@Override
public final void nullSafeSet(PreparedStatement stmt, Object value, int index, SessionImplementor session) throws SQLException {
    if (value == null) {
        stmt.setNull(index, Types.INTEGER);
    } else {
        stmt.setInt(index, ((PersistentEnum) value).getId());
    }
}

@Override
public final Object deepCopy(Object value) {
    return value;
}

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

@Override
public final Serializable disassemble(Object value) {
    return (Serializable) value;
}

@Override
public final Object assemble(Serializable cached, Object owner) {
    return cached;
}

@Override
public final Object replace(Object original, Object target, Object owner) {
    return original;
}

}

public class EtapaAverbacaoUserType extends
    AbstractPersistentEnumUserType<EtapaAverbacao> {

@Override
public Class<EtapaAverbacao> returnedClass() {
    return EtapaAverbacao.class;
}

}

1 个答案:

答案 0 :(得分:1)

经过多方努力,我发现我的团队从查询中返回的对象被提取为只读。

因此,我们在查询中得到提示READ_ONLY,现在可以更新对象