You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Prashant Bhat <pr...@gmail.com> on 2007/07/25 10:10:21 UTC
Modifications to Properties of Basic types inside LifecycleListener do not get saved!
Hi,
I've a mapped super class 'BaseEntity' that has common properties like
Date createdOn; Date updatedOn; boolean active; Company company; User
createdBy; etc.
Initially I used @EntityListeners defined at the BaseEntity and in
LifeCycleEvent handler on PrePersist(), I update these above common
properties.
I wanted my own instance of the listener(or to get hold of it), as I've to
update these from the UI module. But I couldn't find a way to do this in JPA
as it accepts only classes. Thanks to OpenJPA, I could achieve this easily
like this:
if (entityManagerFactory instanceof OpenJPAEntityManagerFactory) {
((OpenJPAEntityManagerFactory)
entityManagerFactory).addLifecycleListener(entityLifecycleHandler, (Class[])
null);
}
But in both the above cases, inside prePersist method, If I set the
properties of type Date or Boolean, they do not get saved.
Other properties like Company, User, etc. are saved properly.
Are the entities passed can not be modified in the listener? Or Is there any
other approach that could achieve this?
Thanks and Regards,
Prashant
Re: Modifications to Properties of Basic types inside LifecycleListener do not get saved!
Posted by Prashant Bhat <pr...@gmail.com>.
Hello Patrick,
I'm using latest openjpa built from source using java 1.5.0_11-b03. (At
runtime I'm using java6) And In my standalone application, I use Spring(
2.0.6) to manage transactions.
o/p of OpenJPAVersion:
OpenJPA 1.0.0-SNAPSHOT
version id: openjpa-1.0.0-SNAPSHOT-r420667:559353
Apache svn revision: 420667:559353
Yes, The test case TestLifecycleListener works with AllFieldTypes entity(I
tried to break it using many approaches, it works!). Actually, I don't find
a logical reason for this kind of behaviour in my application(As enum, other
entity references are saved but not Date, boolean!). Probably, I've made a
mistake somewhere while configuring.
So, I put a breakpoint on the setter of that property(and a out.println) to
check which code is modifying it! Here are my observations:
In beforePersist method -> lastUpdatedOn = Thu Jul 26 19:11:48 SGT 2007
And here lastUpdatedOn = null :->
Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 112 in
BaseEntity))
Role(BaseEntity).pcsetLastUpdatedOn(Date) line: 112
Role(BaseEntity).pcReplaceField(int) line: not available
Role(CompanyEntity).pcReplaceField(int) line: not available
Role.pcReplaceField(int) line: not available
StateManagerImpl.replaceField(PersistenceCapable, FieldManager, int)
line: 2872
StateManagerImpl.settingObjectField(PersistenceCapable, int, Object,
Object, int) line: 1780
VersionAttachStrategy(AttachStrategy).attachField(AttachManager, Object,
StateManagerImpl, FieldMetaData, boolean) line: 179
VersionAttachStrategy.attach(AttachManager, Object, ClassMetaData,
PersistenceCapable, OpenJPAStateManager, ValueMetaData, boolean) line:
134
AttachManager.attach(Object, PersistenceCapable, OpenJPAStateManager,
ValueMetaData, boolean) line: 239
AttachManager.attach(Object) line: 100
BrokerImpl.attach(Object, boolean, OpCallbacks) line: 3186
DelegatingBroker.attach(Object, boolean, OpCallbacks) line: 1147
EntityManagerImpl.merge(T) line: 665
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(Object,
Method, Object[]) line: 180
$Proxy5.merge(Object) line: not available
RoleDaoJpa(BaseDaoJpa<E>).save(E) line: 137
And by this line ->
Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 114 in
BaseEntity))
Role(BaseEntity).pcsetLastUpdatedOn(Date) line: 114
Role(BaseEntity).pcClearFields() line: not available
Role(CompanyEntity).pcClearFields() line: not available
Role.pcClearFields() line: not available
Role.pcNewInstance(StateManager, boolean) line: not available
SaveFieldManager.saveField(int) line: 127
StateManagerImpl.saveField(int) line: 2561
StateManagerImpl.dirty(int, Boolean, boolean) line: 1474
StateManagerImpl.settingStringField(PersistenceCapable, int, String,
String, int) line: 1816
it prints: lastUpdatedOn = null again So it is updated twice to null!
And then it prints, sql-trace logs for getting the next sequence number and
insert query in which these date fields are null!
Sorry for troubling you again. I'm not very familiar with OpenJPA code base,
so I thought posting this could be helpful in finding this issue I'm facing.
Thanks,
Prashant.
On 7/26/07, Patrick Linskey <pl...@gmail.com> wrote:
>
> Hi,
>
> I just added a test case that demonstrates that this works correctly
> --- see https://svn.apache.org/viewvc?view=rev&revision=559515
>
> What version of OpenJPA are you using? Until about a month ago, I
> think that the beforePersist() callback wasn't being invoked at all,
> but that would not result in the symptoms that you're describing.
>
> -Patrick
>
Re: Modifications to Properties of Basic types inside LifecycleListener do not get saved!
Posted by Patrick Linskey <pl...@gmail.com>.
Hi,
I just added a test case that demonstrates that this works correctly
--- see https://svn.apache.org/viewvc?view=rev&revision=559515
What version of OpenJPA are you using? Until about a month ago, I
think that the beforePersist() callback wasn't being invoked at all,
but that would not result in the symptoms that you're describing.
-Patrick
On 7/25/07, Prashant Bhat <pr...@gmail.com> wrote:
> Just to verify this, I added following two properties to
> org.apache.openjpa.persistence.fields.EnumFieldType
> private Date createdOn;
> private boolean active = true;
>
> And modified TestEnumQueryConstructor :
> setup() {
> if (emf instanceof OpenJPAEntityManagerFactory) {
> ((OpenJPAEntityManagerFactory) emf).addLifecycleListener(new
> EntityLifecycleHandler(), (Class[]) null);
> }
> ....
> }
>
> public void testEnumQueryConstructor() {
> ..
> assertEquals(SampleEnum.BAR, e.getEnumField());
> assertNotNull(e.getCreatedOn());
> assertFalse(e.isActive());
> }
>
> public class EntityLifecycleHandler extends AbstractLifecycleListener {
> @Override
> protected void eventOccurred(LifecycleEvent event) {
> switch (event.getType()) {
> case LifecycleEvent.BEFORE_PERSIST:
> if(event.getSource() instanceof EnumFieldType) {
> EnumFieldType e = (EnumFieldType)event.getSource();
> e.setCreatedOn(new Date());
> e.setActive(false);
> e.setEnumField(SampleEnum.BAR);
> }
> break;
> default:
> break;
> }
> }
> }
>
> Both of these fail:
> assertNotNull(e.getCreatedOn());
> assertFalse(e.isActive());
>
> But assertEquals(SampleEnum.BAR, e.getEnumField()); passes the test!
>
> Sorry for not giving a full test case as I'm not very familiar with it! Hope
> this helps.
>
> Thanks and Regards,
> Prashant
>
> On 7/25/07, Prashant Bhat <pr...@gmail.com> wrote:
> >
> > Hi,
> >
> > I've a mapped super class 'BaseEntity' that has common properties like
> > Date createdOn; Date updatedOn; boolean active; Company company; User
> > createdBy; etc.
> >
> > Initially I used @EntityListeners defined at the BaseEntity and in
> > LifeCycleEvent handler on PrePersist(), I update these above common
> > properties.
> > I wanted my own instance of the listener(or to get hold of it), as I've to
> > update these from the UI module. But I couldn't find a way to do this in JPA
> > as it accepts only classes. Thanks to OpenJPA, I could achieve this easily
> > like this:
> >
> > if (entityManagerFactory instanceof OpenJPAEntityManagerFactory) {
> > ((OpenJPAEntityManagerFactory)
> > entityManagerFactory).addLifecycleListener(entityLifecycleHandler, (Class[])
> > null);
> > }
> >
> > But in both the above cases, inside prePersist method, If I set the
> > properties of type Date or Boolean, they do not get saved.
> > Other properties like Company, User, etc. are saved properly.
> >
> > Are the entities passed can not be modified in the listener? Or Is there
> > any other approach that could achieve this?
> >
> > Thanks and Regards,
> > Prashant
> >
> >
>
--
Patrick Linskey
202 669 5907
Re: Modifications to Properties of Basic types inside LifecycleListener do not get saved!
Posted by Prashant Bhat <pr...@gmail.com>.
Just to verify this, I added following two properties to
org.apache.openjpa.persistence.fields.EnumFieldType
private Date createdOn;
private boolean active = true;
And modified TestEnumQueryConstructor :
setup() {
if (emf instanceof OpenJPAEntityManagerFactory) {
((OpenJPAEntityManagerFactory) emf).addLifecycleListener(new
EntityLifecycleHandler(), (Class[]) null);
}
....
}
public void testEnumQueryConstructor() {
..
assertEquals(SampleEnum.BAR, e.getEnumField());
assertNotNull(e.getCreatedOn());
assertFalse(e.isActive());
}
public class EntityLifecycleHandler extends AbstractLifecycleListener {
@Override
protected void eventOccurred(LifecycleEvent event) {
switch (event.getType()) {
case LifecycleEvent.BEFORE_PERSIST:
if(event.getSource() instanceof EnumFieldType) {
EnumFieldType e = (EnumFieldType)event.getSource();
e.setCreatedOn(new Date());
e.setActive(false);
e.setEnumField(SampleEnum.BAR);
}
break;
default:
break;
}
}
}
Both of these fail:
assertNotNull(e.getCreatedOn());
assertFalse(e.isActive());
But assertEquals(SampleEnum.BAR, e.getEnumField()); passes the test!
Sorry for not giving a full test case as I'm not very familiar with it! Hope
this helps.
Thanks and Regards,
Prashant
On 7/25/07, Prashant Bhat <pr...@gmail.com> wrote:
>
> Hi,
>
> I've a mapped super class 'BaseEntity' that has common properties like
> Date createdOn; Date updatedOn; boolean active; Company company; User
> createdBy; etc.
>
> Initially I used @EntityListeners defined at the BaseEntity and in
> LifeCycleEvent handler on PrePersist(), I update these above common
> properties.
> I wanted my own instance of the listener(or to get hold of it), as I've to
> update these from the UI module. But I couldn't find a way to do this in JPA
> as it accepts only classes. Thanks to OpenJPA, I could achieve this easily
> like this:
>
> if (entityManagerFactory instanceof OpenJPAEntityManagerFactory) {
> ((OpenJPAEntityManagerFactory)
> entityManagerFactory).addLifecycleListener(entityLifecycleHandler, (Class[])
> null);
> }
>
> But in both the above cases, inside prePersist method, If I set the
> properties of type Date or Boolean, they do not get saved.
> Other properties like Company, User, etc. are saved properly.
>
> Are the entities passed can not be modified in the listener? Or Is there
> any other approach that could achieve this?
>
> Thanks and Regards,
> Prashant
>
>