空指针EmmbedId类hashCode

时间:2014-12-07 01:28:13

标签: orm playframework-2.0 ebean

我正在编写一个带有Basket,Product和Basket_Product表格的播放应用程序。篮子和产品有多对多关系,存储在Basket_Product中。我正在使用Ebean ORM并收到此错误

[error] Test models.ModelsTest.createAndRetrieveOrder failed: java.lang.NullPointerException: null, took 5.128 sec
[error]     at models.BasketProductPk.hashCode(BasketProductPk.java:43)
[error]     at java.util.HashMap.hash(HashMap.java:338)
[error]     at java.util.HashMap.get(HashMap.java:556)
[error]     at com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext$ClassContext.putIfAbsent(DefaultPersistenceContext.java:175)
[error]     at com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext$ClassContext.access$100(DefaultPersistenceContext.java:148)
[error]     at com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext.putIfAbsent(DefaultPersistenceContext.java:56)
[error]     at com.avaje.ebeaninternal.server.query.SqlTreeNodeBean.load(SqlTreeNodeBean.java:235)
[error]     at com.avaje.ebeaninternal.server.query.CQuery.readRow(CQuery.java:541)
[error]     at com.avaje.ebeaninternal.server.query.CQuery.readBeanInternal(CQuery.java:575)
[error]     at com.avaje.ebeaninternal.server.query.CQuery.hasNextBean(CQuery.java:702)
[error]     at com.avaje.ebeaninternal.server.query.CQuery.readTheRows(CQuery.java:689)
[error]     at com.avaje.ebeaninternal.server.query.CQuery.readCollection(CQuery.java:655)
[error]     at com.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:175)
[error]     at com.avaje.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:77)
[error]     at com.avaje.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:263)
[error]     at com.avaje.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1502)
[error]     at com.avaje.ebeaninternal.server.querydefn.DefaultOrmQuery.findList(DefaultOrmQuery.java:890)
[error]     at com.avaje.ebeaninternal.util.DefaultExpressionList.findList(DefaultExpressionList.java:173)
[error]     at models.ModelsTest.createAndRetrieveOrder(ModelsTest.java:100)

这是我的Junit测试,即抛出错误。当我尝试访问Basket_Product表时。我检查了我的数据库,所有内容都正确插入,我只是在尝试访问特定篮子的Basket_Product时遇到错误。

模型测试方法

@Test
public void createAndRetrieveOrder(){
    Customer walter = Customer.find.where().eq("email", "test@banana_now.com").findUnique();
    Product p1 = Product.find.where().idEq(1).findUnique();
    Product p2 = Product.find.where().idEq(2).findUnique();
    Basket b = new Basket(walter);

    b.save();
    new BasketProduct(p1, b, 2).save();
    new BasketProduct(p2, b, 2).save();

    Basket b1 = Basket.find.where().idEq(8).findUnique();

    List<BasketProduct> bplist = BasketProduct.find.where().eq("basket_id", b1.id).findList();

    assertNotNull(bplist);
}

嵌入式密钥

@Embeddable
public class BasketProductPk implements Serializable{
    @Column(name = "product_id")
    private Product product;
    @Column(name = "basket_id")
    private Basket basket;

    public BasketProductPk(Product product, Basket basket) {
        this.product = product;
        this.basket = basket;
    }
    @Override
    public boolean equals(Object otherOb) {
        if (this == otherOb) {
            return true;
        }
        if (!(otherOb instanceof BasketProductPk)) {
            return false;
        }
        BasketProductPk other = (BasketProductPk) otherOb;
        return (
                (product==null?other.product==null:product.equals
                        (other.product)
                )
                        &&
                        (basket  == other.basket)
        );
    }
    @Override
    public int hashCode() {
        return (
                (product==null?0:product.hashCode())
                        ^
                        (basket.hashCode())
        );
    }

}

篮子产品

@Entity
@Table(name = "basket_product")
public class BasketProduct extends Model {
    @EmbeddedId
    public BasketProductPk id;

    @ManyToOne(cascade= CascadeType.ALL)
    @JoinColumn(name="product_id")
    public Product product;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="basket_id")
    public Basket basket;

    public int quantity;
    public float subtotal;


    public BasketProduct(Product product, Basket basket, int quantity){
        this.id = new BasketProductPk(product, basket);
        this.product = product;
        this.basket = basket;
        this.quantity = quantity;
        this.subtotal = quantity * product.price;
    }
    protected BasketProduct() {}

    public static Finder<String, BasketProduct> find = new Finder<String, BasketProduct>(String.class, BasketProduct.class);
    // getters, setters
}

产品

@Entity
public class Product extends Model{
    @Id
    public int id;
    public String name;
    public Float price;
    public String category;
    public String subcategory;
    public String image_url;
    public String url;
    @ManyToOne
    private Store store;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
    private List<BasketProduct> basket_product;

    public Product(String name, Float price, String category, String subcategory, String image_url, String url, Store store){
        this.name = name;
        this.price = price;
        this.category = category;
        this.subcategory = subcategory;
        this.image_url = image_url;
        this.url = url;
        this.store = store;
    }

    public static Finder<String, Product> find = new Finder<String, Product>(String.class, Product.class);

}

@Entity
public class Basket extends Model {
    @Id
    public int id;
    @CreatedTimestamp
    public Timestamp time;
    int complete;
    @ManyToOne
    public Customer customer;
    @ManyToOne
    public Employee employee;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "basket")
    public  List<BasketProduct> basket_product;

    public Basket(Customer customer){
        this.customer = customer;
        this.complete = 0;
    }
    public Basket(Customer customer, Employee employee){
        this.customer = customer;
        this.employee = employee;
    }

    public static Finder<String, Basket> find = new Finder<String, Basket>(String.class, Basket.class);

}

1 个答案:

答案 0 :(得分:1)

此错误是因为加载BasketProductPk时未加载BasketProduct,且它们都是null

我在你的hashCode方法中看到:

(product==null?0:product.hashCode()) ^ (basket.hashCode())

因此,您检查产品是否为空,但不检查篮子是否为空。所以你的NullPointerException是因为basket为null。

要使此代码正常工作,您必须在代码中进行一些更改: 有关详细信息,请参阅以下答案: