У меня есть пользовательский объект:
@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
}
Где DataObjectAbstract - это простой @MappedSuperClass
, который имеет версию jpa и equals/hashcode.
У меня есть базовый класс dao, который выглядит как
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.
}
Я определил фильтр OpenEntityManagerInView в web.xml следующим образом
<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>
Недавно я обновился до eclipselink 2.3.2 и Spring 3.1 и преобразован из прокси CGLIB в Time Time Weaving с aspectJ для Spring, но я не настроил LTW для eclipselink.
Проблема заключается в этом коде, который находится в Spring ApplicationListener, см. комментарии.
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 просто устанавливает некоторые поля и возвращает this
Я уверен, что он проходит через код, потому что я получаю инструкции журнала вокруг него, и я могу установить точку останова и пройти через нее. Мой журнал postgres не показывает, какой трафик попадает в postgres для слияния.
Я сохраняю другие вещи повсюду без проблем, включая пользователей в другом месте, когда они меняют свой пароль, и я знаю, что этот код использовался для работы. Здесь что-то явно не так? Я неправильно использую OpenEntityManagerInViewFilter? Должен ли я быть в методе @Transactional для того, чтобы объекты считались управляемыми? Любая помощь приветствуется.
Обновление Я попробовал флеш, как предложил прайиш. Здесь код
@Transactional
public T merge( T entity )
{
entity = em.merge( entity );
em.flush();
return entity;
}
в классе в com.bi.data
. У меня это в моем конфигурационном файле Spring
<context:component-scan base-package="com.bi.controller,com.bi.data,com.bi.web" />
В моей конфигурации Spring у меня есть
<context:load-time-weaver/>
<tx:annotation-driven mode="aspectj"/>
с aop.xml, который выглядит так:
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.bi..*"/>
</weaver>
</aspectj>
и я получил
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
Итак, что-то явно неправильно сконфигурировано, но что?
Обновление 2: Я вернул свои изменения, чтобы включить время загрузки во времени, и теперь слияние проходит с флешем или без него, но я до сих пор не понимаю, что проблема с LTW...