799 words

PersistenceException: Failed to locate field

#1
2017-10-05 03:14

Hi, have recently been running into this issue when changing the schema:

com.objectdb.o._PersistenceException: Failed to locate field

in this case, adding a primitive String field to an Entity.

pretty sure that in the past schema evolution would not have triggered errors, is this case, a simple new field, shouldn't the policy be to add a null in that field, or other default for that primitive.

Specifically, from:

http://www.objectdb.com/java/jpa/entity/schema

"Fields in the new schema that do not have matching fields in the old schema are initialized with default values (0, false or null)."

is this a bug, or have I somehow configured the database to complain about this?

 

dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #114
#2
2017-10-06 16:33

The schema evolution should work in this case, nothing was changed.

An exception may be thrown if you mix old and new enhancement. Please make sure that after the change you only use a clean build of your application with fresh enhancement.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #2,832
#3
2017-10-06 18:27

Thanks, though I've been using this enhancement for ages (I think it's actually means no enhancement, serialization only):

<entities>
 
    <enhancement agent = "false" reflection = "warning"/>
 
    <cache ref = "weak" level2 = "20m"/>
 
    <fetch hollow = "true"/>
 
    <persist serialization = "true"/>
 
    <cascade-persist always = "true" on-persist = "true" on-commit = "true"/>
 
    <dirty-tracking arrays = "true"/>
 
  </entities>
dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #115
#4
2017-10-06 18:30

Changed settings to default:

<entities>
    <enhancement agent = "true" reflection = "warning"/>
    <cache ref = "weak" level2 = "20m"/>
    <fetch hollow = "true"/>
    <persist serialization = "false"/>
    <cascade-persist always = "true" on-persist = "true" on-commit = "true"/>
    <dirty-tracking arrays = "true"/>
  </entities>

and still get this error, so that's not the problem.

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: com.objectdb.o._PersistenceException: Failed to locate field field app.model.Auction.name2 using reflection
at com.objectdb.o._PersistenceException.b(_PersistenceException.java:45)
at com.objectdb.o.JPE.g(JPE.java:145)
at com.objectdb.o.ERR.f(ERR.java:55)
at com.objectdb.o.OST.onObjectDBError(OST.java:599)
at com.objectdb.jpa.EMF.createEntityManager(EMF.java:153)
at javax.persistence.EntityManagerFactory$createEntityManager$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at app.database.ObjectDbDatabase.<init>(ObjectDbDatabase.groovy:61)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:255)
at AuServerRedis.<clinit>(AuServerRedis.groovy:79)
Caused by: com.objectdb.o.UserException: Failed to locate field field app.model.Auction.name2 using reflection
at com.objectdb.o.MSG.d(MSG.java:75)
at com.objectdb.o.UMR.P(UMR.java:937)
at com.objectdb.o.UMR$T.i(UMR.java:1065)
at com.objectdb.o.MMM.<init>(MMM.java:299)
at com.objectdb.o.UTY.W(UTY.java:625)
at com.objectdb.o.UTY.S(UTY.java:407)
at com.objectdb.o.TYS.l(TYS.java:171)
at com.objectdb.o.TYM.ae(TYM.java:529)
at com.objectdb.o.MST.UP(MST.java:1163)
at com.objectdb.o.WRA.UP(WRA.java:213)
at com.objectdb.o.STC.m(STC.java:340)
at com.objectdb.o.SHN.ad(SHN.java:388)
at com.objectdb.o.SHN.K(SHN.java:133)
at com.objectdb.o.HND.run(HND.java:133)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchFieldException: name2
at java.lang.Class.getDeclaredField(Class.java:2070)
at com.objectdb.o.UMR$T.i(UMR.java:1060)
... 12 more
dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #116
#5
2017-10-06 18:37

The stack trace is thrown on the server side. Maybe the server has access to an old version of the class (in its classpath) without the new field.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #2,834
#6
2017-10-06 18:41

I'm wondering if any of the classes are actually being enhanced.

I'm not using command line enhancement, nor programmatic enhancement, just relying on the config setting:

<enhancement agent = "true" reflection = "warning"/>

Am wondering if there is a way to know what settings ODB is using when it starts up?

Would be useful to log the location of the config file it is using, plus the contents of that config file, given that I've found many cases where the config file it's actually using isn't as expected, eg. in production vs development.

So, would be useful to log, at startup, current config file location and contents.

So, back to this question: does schema evolution work where you're relying only on the enhancement setting in the config file?

dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #117
#7
2017-10-06 18:48

You may not be using enhancement. But schema evolution should still work.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #2,835
#8
2017-10-06 18:44

ok, so problem resolves if I add programmatic enhancement:

static void main ( args ) {
 
    com.objectdb.Enhancer.enhance("app.model.*");

Note: I removed programmatic many years ago because of some issue which I believe may have been related to my use of groovy instead of java. But, now it seems to be working fine.

I would still consider it a bug that enhancement based only on the XML agent=true flag, and no command line or programmatic enhancement, complains about schema evolution.

Or, at least there should be a note that enhancement based only on the XML setting won't allow schema evolution.

dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #118
#9
2017-10-06 18:52

not sure how to debug your question re the server having access to an old version,

shouldn't it automatically flush it's caches if the schema evolves?

or at least shouldn't that be a user setting?

Anyway the problem goes away with programmatic enhancement, which if I recall from the past, adds setters and getters and is much faster, or has that changed?

 

dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #119
#10
2017-10-06 18:57

There is a warning in the documentation (at the end of the Enhancer page) against the configuration based enhancement, which in some environments doesn't work (it is not something in the control of ObjectDB). Note that your current enhancement call is also not perfect, as it may fail if class for enhancement is loaded by the JVM before enhancement, but as long as it works it is fine.

Reflection should still work, including in schema evolution, and the cause for this failure is still unclear. But enhancement is certainly recommended in production as it produces faster code.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
support
support's picture
Joined on 2010-05-03
User Post #2,836
#11
2017-10-06 19:36
Thanks, I did notice that I needed to run the program twice to get enhancement to work. There is a block static { .... } So perhaps I should out the enhancement code in there first or have a proxy class which calls the main class, if I recall that was the recommended solution But having to run it twice is fine for me.
dmoshal
dmoshal's picture
Joined on 2010-05-22
User Post #120

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel