wisdom-framework / wisdom-orientdb

Wisdom OrientDB integration
Apache License 2.0
2 stars 3 forks source link

Can't read my model , NPE ?? #18

Closed hboumedane closed 9 years ago

hboumedane commented 9 years ago

I have a simple model persisted to my orientdb database. when I try to get a list of all models i'm having this error (I'm strugglin with this since yesterday) :

Method threw 'com.orientechnologies.orient.core.exception.ODatabaseException' exception. Cannot evaluate com.orientechnologies.orient.core.record.impl.ODocument.toString()

any idea were this error came from ?

barjo commented 9 years ago

Hi,

That doesn't ring a bell for me. Can you give a bit more of context on what is the model you are trying to list, and how you try to get the list.

barjo commented 9 years ago

Ah, Can you try implementing the toString method in your model ? Or have you override it. It's possible that some problem occur when Orient call toString on your model.

hboumedane commented 9 years ago

here my model :

@Entity
@JsonIgnoreProperties(value = {"handler"})
public class TokenApi
{
    @Id
    private String id;

    private String token;

    private Date created = Calendar.getInstance().getTime();

    public TokenApi() 
    {
    }

    public String getId() 
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

    public String getToken() 
    {
        return token;
    }

    public void setToken(String token)
    {
        this.token = token;
    }

    public Date getCreated() 
    {
        return created;
    }

    public void setCreated(Date created)
    {
        this.created = created;
    }
}

and inside my component i do :

    @Model(value = TokenApi.class)
    private OrientDbCrud<TokenApi,String> _tokenCrud;

List<TokenApi> _listOfTokens = Utils.toList(_tokenCrud.findAll()); // here a get list of all my token
and here i get the exception that i mentioned before 
hboumedane commented 9 years ago

even with toString() i got the same exception and i can't read value of my object (NPE)

barjo commented 9 years ago

Do you know if it's the toList ? or findAll that trigger the NPE ? or is it after ?

hboumedane commented 9 years ago

not exactly, the NPE is triggered when i try to access my object , the findall give me a list and when i inspect that list i found all field are null and one filed containt the excption :

Method threw 'com.orientechnologies.orient.core.exception.ODatabaseException' exception. Cannot evaluate com.orientechnologies.orient.core.record.impl.ODocument.toString()
barjo commented 9 years ago

Oh I see, that's peculiar. Can you try without the Calendar.getInstance().getTime(); initialization. It may cause some serialization problem.

barjo commented 9 years ago

One things, if you use the @Id annotation and change the id by yourself, it's gonna mess up orientdb Id. It may be good to remove the setId method, if you use the @Id annotation.

hboumedane commented 9 years ago

i removed the setid and tryed without the Calendar.getInstance().getTime(); and still the same exception !!!

barjo commented 9 years ago

I couldn't reproduce with this model , it's strange :-? Can you try with the snapshots 0.2.3. I will go back home and investigate a bit more.

hboumedane commented 9 years ago

I'm already using the 0.2.3 snapshot

barjo commented 9 years ago

If you can send me the code, I will have a look at it :) and see if I can find the problem.

hboumedane commented 9 years ago

you have the model code above and here the other code :

@Component
@Provides
@Instantiate
public class TimeFilter  implements Filter {

      /*workaround to get this class imported to the classpath javassist.util.proxy.Proxy*/
    static {Class workaround = Proxy.class;}

    @Model(value = TokenApi.class)
    private OrientDbCrud<TokenApi,String> _tokenCrud;

    private static final Logger LOGGER = LoggerFactory.getLogger(TimeFilter.class.getName());

    private static final Pattern REGEX = Pattern.compile("/*.*");

    private TokenApi[] _listOfTokens;

    public Result call(Route route, RequestContext context) throws Exception {
        final long begin = System.currentTimeMillis();
        try {
               for(TokenApi tk : _listOfTokens)
                {
                    if(tk.getToken().equals(httpToken))
                    {
                        System.out.print("founded !!! ");
                    }                    
                }
            return context.proceed();
        } finally {
            final long end = System.currentTimeMillis();
            LOGGER.info("Time spent to reply to {} {} : {} ms",
                    route.getHttpMethod(), context.context().path(),
                    (end - begin));
        }
    }

    public Pattern uri() {
        return REGEX;
    }

    public int priority() {
        return 100;
    }

    @Validate
    public void start()
    {
        _listOfTokens = Iterables.toArray(_tokenCrud.findAll(), TokenApi.class);
    }
}
barjo commented 9 years ago

Ok, thanks I will try to reproduce it today.

hboumedane commented 9 years ago

thanks a lot , cause a i'm stuck here

barjo commented 9 years ago

I can reproduce, it's awkward.

hboumedane commented 9 years ago

is there a solution to this !!

barjo commented 9 years ago

Ah I think, I found the problem. it's very strange, maybe related to thread and transaction. Basically, if I print out the TokenApi from the same thread that create them, it seems that it shows null value for it, which is awkward. But if you call it from an other thread, for example, from a controller it works well. I will check the default transaction and fetching behavior with orientdb.

hboumedane commented 9 years ago

let me know if you found some solution !! pls.

barjo commented 9 years ago

Must be some lazy instanciation, or writing in the db as default behavior or something like that.

barjo commented 9 years ago

Uhmm I understand the problem, basically the object that you get from orientdb is a proxy, a lazy proxy. If there is no call to let's say getId, or getToken, it won't load the field from the db, and your toString method will have null field, but if you call the method, you shouldn't have this problem. The strnage stuff, it's that it appens even when lazyloading set to false.

hboumedane commented 9 years ago

yes, exactly even if i call one method from the model i get NPE !! it's strange because i have others models taht are working fine !!!

barjo commented 9 years ago

Ah in my version I don't have this problem :-? let me recheck carefully.

barjo commented 9 years ago

I create a zip of my project here: https://dl.dropboxusercontent.com/u/5560043/hboumedane-sample.zip let me now if that work out for you.

hboumedane commented 9 years ago

it's working now !! thanks a lot, but still don't understand where was the problem ?

barjo commented 9 years ago

I am not fully sure too, without the original code and conf. But definitively something related to the lazy-loading and field access. By the way, don't put any field initialization in the constructor or within the field declaration, otherwise it will override the value each time a proxy is created. It's a bit tricky, but that's how orientdb proxy are working.