我遇到了一个问题,我的事务由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;
}
}
答案 0 :(得分:1)
经过多方努力,我发现我的团队从查询中返回的对象被提取为只读。
因此,我们在查询中得到提示READ_ONLY,现在可以更新对象