【问题标题】:ManyToMany query using play and ebean使用 play 和 ebean 进行多对多查询
【发布时间】:2014-03-01 20:35:30
【问题描述】:

我正在尝试使用具有多对多关系的查找器进行查询,但无法弄清楚这一点。使用 play 2.1.2 和 ebean 3.1.1(与 Play 打包)。

我有一个包含 MyContacts 和 MyContactGroups 的 MyUser 类。 MyContactGroups 与 MyContact 有一个多对多。我正在尝试编写一个查询,我可以在其中获取 MyUser 的 MyContactGroup 中的所有 MyContacts。下面查询失败的方法是findByContactGroupAndUser。

实体是:

@Entity
@Table(name = "my_user")
public class MyUser extends Model {

    @Id
    public Long id;

    public String name;

    @OneToMany(cascade = CascadeType.ALL)
    public List<MyContact> myContacts = new ArrayList<MyContact>();

    @OneToMany(cascade = CascadeType.ALL)
    public List<MyContactGroup> myContactGroups = new ArrayList<MyContactGroup>();

    public void addContact(MyContact myContact) {
        myContacts.add(myContact);
    }

    public void addContactGroup(MyContactGroup myContactGroup) {
        myContactGroups.add(myContactGroup);
    }
    public static Model.Finder<Long, MyUser> find = new Model.Finder<Long, MyUser>(
            Long.class, MyUser.class);
}

@Entity
@Table(name = "my_contact")
public class MyContact extends Model {
    @Id
    public Long id;
    public String name;

    @ManyToOne
    public MyUser myUser;

    @ManyToMany(mappedBy = "myContacts")
    public MyContactGroup myContactGroup;

    public static Model.Finder<Long, MyContact> find = new Model.Finder<Long, MyContact>(
            Long.class, MyContact.class);

    public static Page<MyContact> findByContactGroupAndUser(MyUser myUser, MyContactGroup myContactGroup, int pageSize, int page) {
        return  find.where(Expr.and(Expr.eq("myContactGroup", myContactGroup),
                    Expr.eq("myUser", myUser)))
                    .findPagingList(pageSize).setFetchAhead(false).getPage(page);
    }
}

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

    public String name;

    @ManyToOne(cascade = CascadeType.ALL)
    public MyUser myUser;

    @ManyToMany(cascade = CascadeType.ALL)
    public List<MyContact> myContacts = new ArrayList<MyContact>();


    public void addContact(MyContact myContact) {
        myContacts.add(myContact);
    }

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

测试:

@Test
    public void testMyContactGroup() {
        MyUser myUser = new MyUser();
        myUser.name = "UserSteve";
        myUser.save();

        MyContact myContact = new MyContact();
        myContact.name = "ContactBob";
        myContact.myUser = myUser;

        myUser.addContact(myContact);
        myUser.save();

        assertThat(MyUser.find.where().eq("name", "UserSteve").findUnique().name.equals("UserSteve"));
        assertThat(myUser.myContacts.get(0).name.equals("ContactBob"));

        MyContactGroup myContactGroup = new MyContactGroup();
        myContactGroup.name = "myContactGroup";
        myContactGroup.myUser = myUser;

        myUser.addContactGroup(myContactGroup);
        myUser.update();
        assertThat(myUser.myContactGroups.get(0).name.equals("myContactGroup"));
        myContactGroup = myUser.myContactGroups.get(0);
        myContactGroup.addContact(myContact);


        myUser.update();
        Ebean.saveManyToManyAssociations(myContactGroup, "myContacts");
        myUser = MyUser.find.where().eq("name", "UserSteve").findUnique();
        assertThat(myUser.myContactGroups.get(0).name.equals("myContactGroup"));
        assertThat(myUser.myContactGroups.get(0).myContacts.get(0).name.equals("ContactBob"));


        myUser = MyUser.find.where().eq("name", "UserSteve").findUnique();
        myContactGroup = myUser.myContactGroups.get(0);
        assertThat(myContactGroup.name.equals("myContactGroup"));
        assertThat(myUser.myContactGroups.get(0).myContacts.get(0).name.equals("ContactBob"));
        log.info("doing lookup");

        Page<MyContact> page = MyContact.findByContactGroupAndUser(myUser, myContactGroup, 10, 0);
        assertThat(page.getList().size() == 1);
}

例外:

javax.persistence.PersistenceException: java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at com.avaje.ebeaninternal.server.query.LimitOffsetPage.getList(LimitOffsetPage.java:64)
    at ApplicationTest.testMyContactGroup(ApplicationTest.java:152)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
    at java.util.concurrent.FutureTask.get(FutureTask.java:111)
    at com.avaje.ebeaninternal.server.query.BaseFuture.get(BaseFuture.java:29)
    at com.avaje.ebeaninternal.server.query.LimitOffsetPage.getList(LimitOffsetPage.java:62)
    ... 29 more
Caused by: java.lang.NullPointerException
    at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne.getAssocOneIdValues(BeanPropertyAssocOne.java:411)
    at com.avaje.ebeaninternal.server.expression.SimpleExpression.addBindValues(SimpleExpression.java:50)
    at com.avaje.ebeaninternal.server.expression.LogicExpression.addBindValues(LogicExpression.java:56)
    at com.avaje.ebeaninternal.util.DefaultExpressionList.buildBindValues(DefaultExpressionList.java:277)
    at com.avaje.ebeaninternal.server.query.CQueryPredicates.prepare(CQueryPredicates.java:281)
    at com.avaje.ebeaninternal.server.query.CQueryPredicates.prepare(CQueryPredicates.java:263)
    at com.avaje.ebeaninternal.server.query.CQueryBuilder.buildQuery(CQueryBuilder.java:200)
    at com.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:162)
    at com.avaje.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:77)
    at com.avaje.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:272)
    at com.avaje.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1502)
    at com.avaje.ebeaninternal.server.query.CallableQueryList.call(CallableQueryList.java:26)
    at com.avaje.ebeaninternal.server.query.CallableQueryList.call(CallableQueryList.java:15)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at com.avaje.ebeaninternal.server.lib.thread.PooledThread.doTheWork(PooledThread.java:89)
    at com.avaje.ebeaninternal.server.lib.thread.PooledThread.run(PooledThread.java:62)
    at java.lang.Thread.run(Thread.java:722)

【问题讨论】:

    标签: playframework-2.0 ebean


    【解决方案1】:

    我认为这基本上是因为我没有将 mappedBy 放在正确的实体上,并且可能将 Ebean 直接字段访问与 setter/getter 访问混合在一起。在 play 中,他们说您应该只使用 setter/getter 访问,因为 play 和 Ebean 代码增强之间存在一些冲突。以下直接与 Ebean 一起工作,我也能够让它在游戏中工作。

    package app.data;
    
    import com.avaje.ebean.validation.Length;
    
    import javax.persistence.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by aakture on 3/2/14.
     */
    @Entity
    @Table(name="o_user")
    public class User {
    
        @Id
        Integer id;
    
        @Length(max = 20)
        String name;
    
        @OneToMany(cascade = CascadeType.ALL)
        List<ContactGroup> contactGroups = new ArrayList<ContactGroup>();
    
        @OneToMany(cascade = CascadeType.ALL)
        List<Contact> contacts = new ArrayList<Contact>();
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<ContactGroup> getContactGroups() {
            return contactGroups;
        }
    
        public void setContactGroups(List<ContactGroup> contactGroups) {
            this.contactGroups = contactGroups;
        }
    
        public List<Contact> getContacts() {
            return contacts;
        }
    
        public void setContacts(List<Contact> contacts) {
            this.contacts = contacts;
        }
    
        @Override
        public String toString() {
            return com.google.common.base.Objects.toStringHelper(this)
                    .add("id", id)
                    .add("name", name)
                    .add("contactGroups", contactGroups)
                    .toString();
        }
    }
    
    
    package app.data;
    
    import javax.persistence.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by aakture on 3/2/14.
     */
    @Entity
    @Table(name="o_contact")
    public class Contact {
        @Id
        Integer id;
    
        String name;
    
        @ManyToOne
        User user;
    
        @ManyToMany
        List<ContactGroup> contactGroups = new ArrayList<ContactGroup>();
    
        public List<ContactGroup> getContactGroups() {
            return contactGroups;
        }
    
        public void setContactGroups(List<ContactGroup> contactGroups) {
            this.contactGroups = contactGroups;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
    
    }
    
    
    
    package app.data;
    
    import javax.persistence.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by aakture on 3/2/14.
     */
    @Entity
    @Table(name="o_contact_group")
    public class ContactGroup {
    
        @Id
        Integer id;
    
        @ManyToOne
        User user;
    
        String name;
        @ManyToMany(cascade = CascadeType.MERGE, mappedBy = "contactGroups")
        List<Contact> contacts = new ArrayList<Contact>();
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        public List<Contact> getContacts() {
            return contacts;
        }
    
        public void setContacts(List<Contact> contacts) {
            this.contacts = contacts;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    测试:

        public void test() {
            User user = new User();
            user.setName("UserBob");
            Ebean.save(user);
    
    
    
            ContactGroup contactGroup = new ContactGroup();
            contactGroup.setName("Friends");
    
            List<ContactGroup> contactGroupList = new ArrayList<ContactGroup>();
            contactGroupList.add(contactGroup);
            user.setContactGroups(contactGroupList);
    
            Ebean.update(user);
    
            user = Ebean.find(User.class).where().eq("name", "UserBob").findUnique();
            List<ContactGroup> contactGroups = user.getContactGroups();
    
            for(ContactGroup cg : contactGroups) {
                System.out.println("contactGroup: " + cg.getName());
            }
    
            Contact contact = new Contact();
            contact.setName("ContactSteve");
            user.getContacts().add(contact);
    
            Ebean.update(user);
    
            user = Ebean.find(User.class).where().eq("name", "UserBob").findUnique();
            for(Contact c : user.getContacts()) {
                System.out.println("contact: " + c.getName());
            }
            Contact contactSteve = user.getContacts().get(0);
            ContactGroup friends = user.getContactGroups().get(0);
            friends.getContacts().add(contactSteve);
    
            Ebean.saveManyToManyAssociations(friends, "contacts");
    
            Ebean.update(user);
            user = Ebean.find(User.class).where().eq("name", "UserBob").findUnique();
    
            friends = user.getContactGroups().get(0);
            List<Contact> contacts = friends.getContacts();
            for (Contact c : contacts) {
                System.out.println("contact: " + c.getName());
            }
    
            contact = Ebean.find(Contact.class).where().and(Expr.eq("user.name", "UserBob"), Expr.eq("contactGroups.name", "Friends")).findUnique();
    
            System.out.println("contact: " + contact.getName());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多