cancel
Showing results for 
Search instead for 
Did you mean: 

SAP-JPA changes version of unchanged entities

Former Member
0 Kudos

Hi all:

We are having a problem with an application that we developed using Sap NetWeaver 7.1 . We are having optimisticlock exception in some of the transactions that we have in the application, checking this situation we found that SAP-JPA is updating the version field for entities that we haven't change. Why is this happening?

Accepted Solutions (0)

Answers (1)

Answers (1)

adrian_goerler
Employee
Employee
0 Kudos

Hi,

SAP JPA should be updating the version of an entity iff

- a non-relationship attribute of the entity is changed

- a relationship attribute owned by the entity is changed

- the entity has been locked with lock mode WRITE

If you experience version updates in other circumstances, we'd have to look into the issue in detail.

-Adrian

Former Member
0 Kudos

Hi Adrian:

Thanks for the quick response. We have seen that it is changing this field right after we execute a query on the database, we check the database trace and we saw that when it runs the query it brings the entity and all the entities associated but after all the selects it fires an update on every single entity it brings.

Is there something we are doing wrong? Or this is the normal behavior?

Regards

Jose Arango

Edited by: José Fernando Arango Jimenez on Feb 13, 2009 3:49 AM

Edited by: José Fernando Arango Jimenez on Feb 13, 2009 3:54 AM

adrian_goerler
Employee
Employee
0 Kudos

Hi,

could you please provide us with the query in question and the related entities?

-Adrian

Former Member
0 Kudos

Hi Adrian:

I'm sending the following:

1. The ejb's method that we are using to execute the query.

2. The query.

3. The entities that are part of the query, if you need I can send you the related entities.

This is the method that we are calling from webDynpro.

@TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED)

public List<Object> buscarOrdenesFabricacion(String codigoLote){

ArrayList<Object> listaParametros = new ArrayList<Object>();

listaParametros.add(codigoLote);

Parametro parametro = new Parametro();

parametro.setParametros(listaParametros);

//parametro = null;

List<Object> ordenFabricacion = (List<Object>)servicioCrud.findNamedQuery("OrdenFab.buscarPor_Lote_tipoSemi", parametro);

if(ordenFabricacion.size() == 0){

return null;

}

return ordenFabricacion;

}

This method is from an EJB that we use to handle all the DB interaction (DAO)

@TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED)

public List findNamedQuery(String namedQuery, Parametro parametro) {

super.setEntityManager(this.entityManager);

return super.findNamedQuery(namedQuery, parametro);

}

In this EJB we are intantiating the entityManager in this way

@PersistenceContext(unitName="devCrystal~0~entidades~crystal.com.co")

protected EntityManager entityManager;

@Resource(name="ORDENES")

protected javax.sql.DataSource dataSource;

We are handling the transaction by BEAN.

This is the parent class for the above EJB.

@TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED)

public List findNamedQuery(String namedQuery, Parametro parametro) {

List retorno = null;

Query query = this.entityManager.createNamedQuery(namedQuery).setFlushMode(FlushModeType.COMMIT);

setParametros(query, parametro);

retorno = query.getResultList();

return retorno;

}

protected Query setParametros(Query query, Parametro parametro) {

if (parametro != null) {

List<Object> listaParametros = parametro.getParametros();

if (parametro != null && listaParametros != null) {

for (int i = 1; i <= listaParametros.size(); i++) {

query.setParameter(i, listaParametros.get(i - 1));

}

}

}

return query;

}

QUERY

<named-native-query name="OrdenFab.buscarPor_Lote_tipoSemi" result-class="co.com.crystal.entidades.produccion.OrdenFabricacion">

<query><![CDATA[ SELECT of.*

FROM tb_ordenfabricacion of

WHERE of.co_ordenfabricacion IN

(SELECT DISTINCT tb_operacionlote.co_ordenfabricacion

FROM tb_operacionlote

WHERE tb_operacionlote.fh_terminacion IS NULL AND tb_operacionlote.co_lote = ?)]]>

</query>

</named-native-query >

Entities

package co.com.crystal.entidades.produccion;

import java.io.Serializable;

import java.sql.Timestamp;

import java.util.List;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.persistence.Transient;

import javax.persistence.Version;

@Entity

@Table(name="TB_ORDENFABRICACION")

public class OrdenFabricacion implements Serializable {

@Id

@Column(name="CO_ORDENFABRICACION")

private String coOrdenfabricacion;

@Column(name="FH_ACTUALIZACION")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhActualizacion;

@Column(name="CA_PROGRAMADA")

private Double caProgramada;

@Version

private int version;

@Column(name="SW_SUMINISTROILIMITADO", nullable = true)

private String swSuministroilimitado;

@Column(name="CO_USUARIO")

private String coUsuario;

@Column(name="FH_CREACION")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhCreacion;

@Column(name="VL_PORCENTAJEEXCESO", nullable = true)

private Double vlPorcentajeexceso;

@ManyToOne

@JoinColumn(name="CO_TIPOSEMIELABORADO", nullable = true)

private TipoSemiElaborado coTiposemielaborado;

@ManyToOne

@JoinColumn(name="CO_CENTRO")

private Centro coCentro;

@ManyToOne

@JoinColumn(name="CO_CATEGORIA", nullable = true)

private Categoria coCategoria;

@ManyToOne

@JoinColumn(name="CO_CLASEORDEN")

private ClaseOrden coClaseorden;

@ManyToOne

@JoinColumn(name="CO_MATERIAL")

private Material coMaterial;

@ManyToOne

@JoinColumn(name="CO_TALLA")

private Talla coTalla;

@ManyToOne

@JoinColumn(name="CO_COLOR")

private Color coColor;

/* //@OneToMany(mappedBy="coOrdenfabricacion", fetch=FetchType.LAZY)

@Transient

private List<OperacionLote> tbOperacionLoteCollection;

@OneToMany(mappedBy="coOrdenfabricacion", fetch=FetchType.LAZY)

private List<OperacionOrden> tbOperacionordenCollection;

@OneToMany(mappedBy="coOrdenfabricacion")

private Set<OrdenPrevFab> tbOrdenprevfabCollection;

@OneToMany(mappedBy="coOrdenfabricacion")

private Set<OrdenPrevFab> tbOrdenprevfabCollection;

*/

private static final long serialVersionUID = 1L;

public OrdenFabricacion() {

super();

}

public String getCoOrdenfabricacion() {

return this.coOrdenfabricacion;

}

public void setCoOrdenfabricacion(String coOrdenfabricacion) {

this.coOrdenfabricacion = coOrdenfabricacion;

}

public Timestamp getFhActualizacion() {

return this.fhActualizacion;

}

public void setFhActualizacion(Timestamp fhActualizacion) {

this.fhActualizacion = fhActualizacion;

}

public Double getCaProgramada() {

return this.caProgramada;

}

public void setCaProgramada(Double caProgramada) {

this.caProgramada = caProgramada;

}

public Centro getCoCentro() {

return this.coCentro;

}

public void setCoCentro(Centro coCentro) {

this.coCentro = coCentro;

}

public int getVersion() {

return this.version;

}

public void setVersion(int version) {

this.version = version;

}

public String getSwSuministroilimitado() {

return this.swSuministroilimitado;

}

public void setSwSuministroilimitado(String swSuministroilimitado) {

this.swSuministroilimitado = swSuministroilimitado;

}

public String getCoUsuario() {

return this.coUsuario;

}

public void setCoUsuario(String coUsuario) {

this.coUsuario = coUsuario;

}

public TipoSemiElaborado getCoTiposemielaborado() {

return this.coTiposemielaborado;

}

public void setCoTiposemielaborado(TipoSemiElaborado coTiposemielaborado) {

this.coTiposemielaborado = coTiposemielaborado;

}

public Timestamp getFhCreacion() {

return this.fhCreacion;

}

public void setFhCreacion(Timestamp fhCreacion) {

this.fhCreacion = fhCreacion;

}

public Double getVlPorcentajeexceso() {

return this.vlPorcentajeexceso;

}

public void setVlPorcentajeexceso(Double vlPorcentajeexceso) {

this.vlPorcentajeexceso = vlPorcentajeexceso;

}

public Categoria getCoCategoria() {

return this.coCategoria;

}

public void setCoCategoria(Categoria coCategoria) {

this.coCategoria = coCategoria;

}

public ClaseOrden getCoClaseorden() {

return this.coClaseorden;

}

public void setCoClaseorden(ClaseOrden coClaseorden) {

this.coClaseorden = coClaseorden;

}

public Material getCoMaterial() {

return this.coMaterial;

}

public void setCoMaterial(Material coMaterial) {

this.coMaterial = coMaterial;

}

public Talla getCoTalla() {

return this.coTalla;

}

public void setCoTalla(Talla coTalla) {

this.coTalla = coTalla;

}

public Color getCoColor() {

return this.coColor;

}

public void setCoColor(Color coColor) {

this.coColor = coColor;

}

/*

public List<OperacionOrden> getTbOperacionordenCollection() {

return this.tbOperacionordenCollection;

}

public void setTbOperacionordenCollection(List<OperacionOrden> tbOperacionordenCollection) {

this.tbOperacionordenCollection = tbOperacionordenCollection;

}

public Set<Lote> getTbLoteCollection() {

return tbLoteCollection;

}

public void setTbLoteCollection(Set<Lote> tbLoteCollection) {

this.tbLoteCollection = tbLoteCollection;

}

public Set<OrdenPrevFab> getTbOrdenprevfabCollection() {

return this.tbOrdenprevfabCollection;

}

public void setTbOrdenprevfabCollection(Set<OrdenPrevFab> tbOrdenprevfabCollection) {

this.tbOrdenprevfabCollection = tbOrdenprevfabCollection;

}

public Set<TbOrdenprevfab> getTbOrdenprevfabCollection() {

return this.tbOrdenprevfabCollection;

}

public void setTbOrdenprevfabCollection(Set<TbOrdenprevfab> tbOrdenprevfabCollection) {

this.tbOrdenprevfabCollection = tbOrdenprevfabCollection;

}

public List<OperacionLote> getTbLoteCollection() {

return tbOperacionLoteCollection;

}

public void setTbLoteCollection(List<OperacionLote> tbLoteCollection) {

this.tbOperacionLoteCollection = tbLoteCollection;

}

*/

}

package co.com.crystal.entidades.produccion;

import java.io.Serializable;

import java.sql.Timestamp;

import javax.persistence.Column;

import javax.persistence.Embeddable;

import javax.persistence.EmbeddedId;

import javax.persistence.Entity;

import javax.persistence.JoinColumn;

import javax.persistence.JoinColumns;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.persistence.Version;

@Entity

@Table(name="TB_OPERACIONLOTE")

public class OperacionLote implements Serializable {

@EmbeddedId

private OperacionLote.PK pk;

@Column(name="CA_PRIMERAS")

private Integer caPrimeras;

@Column(name="FH_TERMINACION")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhTerminacion;

@Column(name="FH_INICIO")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhInicio;

@Column(name="FH_ACTUALIZACION")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhActualizacion;

@Column(name="FH_CREACION")

@Temporal(TemporalType.TIMESTAMP)

private Timestamp fhCreacion;

@Version

private int version;

@Column(name="CO_USUARIO")

private String coUsuario;

@Column(name="CA_TEORICA")

private Double caTeorica;

@Column(name="CA_TEORICAPLC")

private Double caTeoricaplc;

@ManyToOne

@JoinColumn(name="CS_MAQUINA")

private Maquina csMaquina;

@Column(name="CO_MAQUINA")

private String coMaquina;

@ManyToOne

@JoinColumns({

@JoinColumn(name="CO_ORDENFABRICACION", referencedColumnName="CO_ORDENFABRICACION", insertable=false, updatable=false),

@JoinColumn(name="CO_LOTE", referencedColumnName="CO_LOTE", insertable=false, updatable=false)

})

private Lote tbLote;

@ManyToOne

@JoinColumns({

@JoinColumn(name="CO_ORDENFABRICACION", referencedColumnName="CO_ORDENFABRICACION", insertable=false, updatable=false),

@JoinColumn(name="CS_OPERACION", referencedColumnName="CS_OPERACION", insertable=false, updatable=false)

})

private OperacionOrden tbOperacionOrden;

private static final long serialVersionUID = 1L;

public OperacionLote() {

super();

}

public OperacionLote.PK getPk() {

return this.pk;

}

public void setPk(OperacionLote.PK pk) {

this.pk = pk;

}

public Integer getCaPrimeras() {

return this.caPrimeras;

}

public void setCaPrimeras(Integer caPrimeras) {

this.caPrimeras = caPrimeras;

}

public Timestamp getFhTerminacion() {

return this.fhTerminacion;

}

public void setFhTerminacion(Timestamp fhTerminacion) {

this.fhTerminacion = fhTerminacion;

}

public Timestamp getFhInicio() {

return this.fhInicio;

}

public void setFhInicio(Timestamp fhInicio) {

this.fhInicio = fhInicio;

}

public Timestamp getFhActualizacion() {

return this.fhActualizacion;

}

public void setFhActualizacion(Timestamp fhActualizacion) {

this.fhActualizacion = fhActualizacion;

}

public Timestamp getFhCreacion() {

return this.fhCreacion;

}

public void setFhCreacion(Timestamp fhCreacion) {

this.fhCreacion = fhCreacion;

}

public int getVersion() {

return this.version;

}

public void setVersion(int version) {

this.version = version;

}

public String getCoUsuario() {

return this.coUsuario;

}

public void setCoUsuario(String coUsuario) {

this.coUsuario = coUsuario;

}

public Double getCaTeorica() {

return this.caTeorica;

}

public void setCaTeorica(Double caTeorica) {

this.caTeorica = caTeorica;

}

public Double getCaTeoricaplc() {

return this.caTeoricaplc;

}

public void setCaTeoricaplc(Double caTeoricaplc) {

this.caTeoricaplc = caTeoricaplc;

}

@Embeddable

public static class PK implements Serializable {

@Column(name="CO_ORDENFABRICACION")

private String coOrdenfabricacion;

@Column(name="CO_LOTE")

private String coLote;

@Column(name="CS_OPERACION")

private String csOperacion;

private static final long serialVersionUID = 1L;

public PK() {

super();

}

public String getCoLote() {

return this.coLote;

}

public void setCoLote(String coLote) {

this.coLote = coLote;

}

public String getCsOperacion() {

return this.csOperacion;

}

public void setCsOperacion(String csOperacion) {

this.csOperacion = csOperacion;

}

public String getCoOrdenfabricacion() {

return this.coOrdenfabricacion;

}

public void setCoOrdenfabricacion(String coOrdenfabricacion) {

this.coOrdenfabricacion = coOrdenfabricacion;

}

@Override

public boolean equals(Object o) {

if (o == this) {

return true;

}

if ( ! (o instanceof PK)) {

return false;

}

PK other = (PK) o;

return this.coLote.equals(other.coLote)

&& this.csOperacion.equals(other.csOperacion)

&& this.coOrdenfabricacion.equals(other.coOrdenfabricacion);

}

@Override

public int hashCode() {

return this.coLote.hashCode()

^ this.csOperacion.hashCode()

^ this.coOrdenfabricacion.hashCode();

}

}

public Lote getTbLote() {

return tbLote;

}

public void setTbLote(Lote tbLote) {

this.tbLote = tbLote;

}

public OperacionOrden getTbOperacionOrden() {

return tbOperacionOrden;

}

public void setTbOperacionOrden(OperacionOrden tbOperacionOrden) {

this.tbOperacionOrden = tbOperacionOrden;

}

public Maquina getCsMaquina() {

return csMaquina;

}

public void setCsMaquina(Maquina csMaquina) {

this.csMaquina = csMaquina;

}

public String getCoMaquina() {

return coMaquina;

}

public void setCoMaquina(String coMaquina) {

this.coMaquina = coMaquina;

}

}

If you need i can send you also the database traces where you can see the selects and updates over the tables.

I hope that you can help us with this, we are in a huge problem because of this behavior.

Best regards,

Jose Arango.