Re: [ebean] InvocationTargetException when adding children to an entity

150 views
Skip to first unread message

Rob Bygrave

unread,
Jul 5, 2012, 7:37:16 PM7/5/12
to eb...@googlegroups.com
Hmmm. Looks to me like you are putting a new Article instance into a HashSet ... and that means that the hashcode() is getting called ... and it looks like the implementation of hashcode() is trying to use the Long id ... and it's null at the time ... and that is the likely cause of the NPE.

models.ModuleArticle.getId(ModuleArticle.java:53)

To me that implies that the generated implementation of hashcode() is dodgy / not robust / poor. Looking at the stacktrace it is not using the implementation of hashcode() and equals() that Ebean would generate (the debug line number plus the method call to getId rather than getfield implies that). 

Suggests the issue is with the Play generated hashcode() / equals() implementation.


Cheers, Rob.


On 6 July 2012 06:08, F69631 <f69...@gmail.com> wrote:
This is so basic use case that I feel embarrassed for having to ask this... but after hours of Googling, I was unable to find a single good example of this (though there must be many). So...

I have a Play Framework 2.0.1 project with entities Page and Article. One page may have 0...n articles and article always has a reference to the page that contains it. When I retrieve data, everything works: pageObject.getArticles().size() returns the number of articles associated with the page. When I try to add a new article to a page, I get InvocationTargetException... and don't have any idea why that is.

Here are the relevant parts of the code.

/* ARTICLE */

@Entity
@Table(name="articlemodule")
public class ModuleArticle extends Model implements ModuleInterface
{
    @Id
    public Long id;

    @ManyToOne
    @JoinColumn(name="pageId",referencedColumnName="id")
    public Page page;

    public static Finder<Long, ModuleArticle> find = new Finder<Long, ModuleArticle>(Long.class, ModuleArticle.class);
   
    public void setPage(Page page)
    {
    this.page = page;
    }

}


/* PAGE */

@Entity
@Table(name="page")
public class Page extends Model
{
    @Id
    public Long id;

    @OneToMany(targetEntity=ModuleArticle.class,mappedBy="page")
    public Set<ModuleArticle> articles;
    
    public Set<ModuleArticle> getArticles()
    {
    return articles;
    }

    public static Finder<Long, Page> find = new Finder<Long, Page>(Long.class, Page.class);
}

/* CONTROLLER */
public static Result addArticle(Long id, Long pageId)
{
    Page p = Page.find.byId(pageId);
   
    ModuleArticle ma = new ModuleArticle();
    ma.setPage(p);
    p.getArticles().add(ma); /* THIS LINE CAUSES ERROR */
    p.save();
    
    return ok("new size " + p.getArticles().size());
}


/* STACK TRACE */
! @6b08fihim - Internal server error, for request [POST ***url removed*** ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[RuntimeException: java.lang.reflect.InvocationTargetException]]
        at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.1]
        at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.1]
        at akka.actor.Actor$class.apply(Actor.scala:311) [akka-actor.jar:2.0.1]
        at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.1]
        at akka.actor.ActorCell.invoke(ActorCell.scala:619) [akka-actor.jar:2.0.1]
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:196) [akka-actor.jar:2.0.1]
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at play.db.ebean.Model._getId(Model.java:56) ~[play_2.9.1.jar:2.0.1]
        at play.db.ebean.Model.hashCode(Model.java:183) ~[play_2.9.1.jar:2.0.1]
        at java.util.HashMap.put(HashMap.java:389) ~[na:1.6.0_24]
        at java.util.HashSet.add(HashSet.java:217) ~[na:1.6.0_24]
        at com.avaje.ebean.common.BeanSet.add(BeanSet.java:207) ~[ebean.jar:na]
        at controllers.Module.addArticle(Module.java:207) ~[classes/:na]
Caused by: java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_24]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.6.0_24]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.6.0_24]
        at java.lang.reflect.Method.invoke(Method.java:616) ~[na:1.6.0_24]
        at play.db.ebean.Model._getId(Model.java:52) ~[play_2.9.1.jar:2.0.1]
        at play.db.ebean.Model.hashCode(Model.java:183) ~[play_2.9.1.jar:2.0.1]
Caused by: java.lang.NullPointerException: null
        at models.ModuleArticle.getId(ModuleArticle.java:53) ~[classes/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_24]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.6.0_24]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.6.0_24]
        at java.lang.reflect.Method.invoke(Method.java:616) ~[na:1.6.0_24]
        at play.db.ebean.Model._getId(Model.java:52) ~[play_2.9.1.jar:2.0.1]


F69631

unread,
Jul 6, 2012, 2:50:14 AM7/6/12
to eb...@googlegroups.com
Thanks a lot, Rob! I should've been able to figure that out myself from the stack trace but I'm just too quick to dismiss any notion that the problem might be somewhere else than in my code... :)

If I switch the id of article to long instead of Long, I no longer get an exception and the article gets added to the hashmap. However, the object doesn't actually get persisted in the database (I can connect to the DB through terminal and confirm that the data isn't there)... I tried adding @GeneratedValue to article's id in case that would've been the problem but didn't help.

Do I need to do something else in addition to calling save() of the page object? If I try to call it for the article, I get an exception for trying to save the child element. If it fails silently, how should I go on about debugging it? (mysql.log doesn't contain anything about this at least)

Rob Bygrave

unread,
Jul 6, 2012, 4:27:00 AM7/6/12
to eb...@googlegroups.com

There is no cascade persist on page.articles ... So saving page does not cascade save the articles.

A good idea would be to have the transaction logging on do you can see more clearly what is happening.

Cheers, Rob.

F69631

unread,
Jul 6, 2012, 5:18:34 AM7/6/12
to eb...@googlegroups.com
Right. Everything works now! Thanks for the help (and the tip)... You just made my day!

Now, I'll be off to getting some work done again. :)
Reply all
Reply to author
Forward
0 new messages