ho un'entità User:EntityManager.merge non facendo nulla
@Entity
@Table(name = "bi_user")
@SequenceGenerator(name = "USER_SEQ_GEN", sequenceName = "USER_SEQUENCE")
public class User
extends DataObjectAbstract<Long>
{
private static final long serialVersionUID = -7870157016168718980L;
/**
* key for this instance. Should be managed by JPA provider.
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ_GEN")
private Long key;
/**
* Username the user will use to login. This should be an email address
*/
@Column(nullable=false, unique=true)
private String username;
// etc. other columns and getters/setters
}
Dove DataObjectAbstract è un semplice @MappedSuperClass
che ha una versione JPA e uguale/definizione codice hash.
ho una classe di base dao che assomiglia a questo
public abstract class BaseDaoAbstract<T extends DataObject<K>, K extends Serializable>
implements BaseDao<T, K>
{
@PersistenceContext
private EntityManager em;
/**
* Save a new entity. If the entity has already been persisted, then merge
* should be called instead.
*
* @param entity The transient entity to be saved.
* @return The persisted transient entity.
*/
@Transactional
public T persist(T entity)
{
em.persist(entity);
return entity;
}
/**
* merge the changes in this detached object into the current persistent
* context and write through to the database. This should be called to save
* entities that already exist in the database.
*
* @param entity The entity to be merged
* @return The merged entity.
*/
@Transactional
public T merge(T entity)
{
return em.merge(entity);
}
// other methods like persist, delete, refresh, findByKey that all delegate to em.
}
ho definito il filtro OpenEntityManagerInView in web.xml come segue
<filter>
<filter-name>openEntityManagerInViewFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>biEmf</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
recente aggiorno a EclipseLink 2.3.2 e primavera 3.1 e convertiti da proxy CGLIB per caricare Time Weaving con aspectJ per Spring ma non ho configurato LTW per eclipselink.
Il problema è in questo codice che risiede in un ApplicationListener di primavera, vedere i commenti.
User user = userService.findByKey(userDetails.getKey());
// THIS MERGE NEVER WRITES THROUGH TO THE DATABASE.
// THIS DOESN'T WORK AS PERSIST EITHER
user = userService.merge(user.loginSuccess());
user.loginSuccess solo stabilisce alcuni campi e restituisce this
Sono certo che sta facendo con il codice perché ho affermazioni intorno ad esso il login e posso impostare un punto di interruzione e camminare attraverso di essa. Il mio registro postgres non mostra traffico che arriva a postgres per l'unione.
Sto salvando altre cose ovunque senza problemi, compresi gli utenti in un'altra posizione quando cambiano la password e so che questo codice funzionava. C'è qualcosa di evidentemente sbagliato? Sto usando OpenEntityManagerInViewFilter in modo errato? Dovrei aver bisogno di essere in un metodo @Transactional in modo che le entità possano essere considerate gestite? Qualsiasi aiuto è apprezzato.
Aggiornamento Ho provato il colore come suggerito da prajeesh. Ecco il codice
@Transactional
public T merge(T entity)
{
entity = em.merge(entity);
em.flush();
return entity;
}
in una classe in com.bi.data
. Ho questo nel mio primavera app config file di
<context:component-scan base-package="com.bi.controller,com.bi.data,com.bi.web" />
Nella mia configurazione primavera ho
<context:load-time-weaver/>
<tx:annotation-driven mode="aspectj"/>
con un'aop.xml che assomiglia a questo:
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.bi..*"/>
</weaver>
</aspectj>
e ho ottenuto un
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
Quindi qualcosa è ovviamente mal configurato, ma cosa?
Aggiornamento 2: sono ritornato mie modifiche per consentire il tempo di tessitura del carico e ora l'unione passa attraverso con o senza filo, ma io ancora non capisco quale sia il problema con LTW ...
Sembra che la transazione sia configurata correttamente. Forse includi il tuo persistence.xml, assicurati di utilizzare RESOURCE_LOCAL. Abilita la registrazione migliore per vedere cosa sta succedendo. – James
Grazie per le idee James. Lo darò un'occhiata dopo il lavoro. Sono abbastanza sicuro che stiamo usando RESOURCE_LOCAL perché siamo in esecuzione in Tomcat, quindi non l'ho mai fatto. – digitaljoel
Hai provato ad aggiungere propagation = Propagation.REQUIRED all'annotazione @Transactional? –