J'ai une entité utilisateur:EntityManager.merge ne fait rien
@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
}
Où DataObjectAbstract est un @MappedSuperClass
simple qui a une version JPA et égale/définition hashcode.
J'ai une classe dao de base qui ressemble à ceci
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.
}
J'ai défini le filtre OpenEntityManagerInView dans web.xml comme suit
<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>
I récemment mis à jour à EclipseLink 2.3.2 et printemps 3.1 et converti à partir de proxies CGLIB à Load Time Weaving avec aspectJ pour Spring mais je n'ai pas configuré LTW pour eclipselink.
Le problème est dans ce code qui réside dans un Spring ApplicationListener, voir les commentaires.
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 définit juste quelques champs et retourne this
Je suis certain qu'il devient dans le code parce que je reçois des déclarations autour de vous connecter et je peux mettre un point d'arrêt et de marcher à travers elle. Mon journal postgres ne montre aucun trafic accédant à postgres pour la fusion. Je sauve d'autres choses partout sans problème, y compris les utilisateurs dans un autre endroit quand ils changent leur mot de passe, et je sais que ce code a l'habitude de fonctionner. Y a-t-il quelque chose qui cloche ici? Est-ce que j'utilise le OpenEntityManagerInViewFilter de manière incorrecte? Devrais-je être dans une méthode @Transactional pour que les entités soient considérées comme gérées? Toute aide est appréciée.
Mise à jour J'ai essayé le flush comme suggéré par prajeesh. Voici le code
@Transactional
public T merge(T entity)
{
entity = em.merge(entity);
em.flush();
return entity;
}
dans une classe en com.bi.data
. J'ai dans mon fichier de configuration app printemps
<context:component-scan base-package="com.bi.controller,com.bi.data,com.bi.web" />
Dans ma configuration de printemps, j'ai
<context:load-time-weaver/>
<tx:annotation-driven mode="aspectj"/>
avec un aop.xml qui ressemble à ceci:
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.bi..*"/>
</weaver>
</aspectj>
et je suis un
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
Quelque chose est évidemment mal configuré, mais quoi?
Mise à jour 2: Je Reconvertit mes changements pour permettre le tissage de temps de chargement et maintenant la fusion passe par avec ou sans chasse d'eau, mais je ne comprends toujours pas ce que le problème est avec LTW ...
Il semble que vous ayez configuré la transaction correctement. Peut-être inclure votre persistence.xml, assurez-vous que vous utilisez RESOURCE_LOCAL. Activer la journalisation sur les plus fins pour voir ce qui se passe. – James
Merci pour les idées de James. Je vais y jeter un coup d'œil après le travail. Je suis à peu près certain que nous utilisons RESOURCE_LOCAL parce que nous courons dans Tomcat, donc jamais JTA. – digitaljoel
Avez-vous essayé d'ajouter propagation = Propagation.REQUIRED à l'annotation @Transactional? –