Ebean一对多映射不起作用。

时间:2014-12-10 06:30:22

标签: orm playframework playframework-2.0 ebean

我正在撰写一个包含产品,客户,信用卡和购物车的网络应用。客户在信用卡和购物车上都有一对多的映射。在我的客户类中,我有一个列表和列表。当我访问customer.creditCardList时一切正常。当我为customer.shoppingCartList尝试相同时,我得到这个错误。

error] Test models.ModelsTest.createAndRetrieveCart failed: javax.persistence.PersistenceException:
ERROR executing DML bindLog[] error[Field 'customer_id' doesn't have a default value]

在我没有收到任何错误之前,我的shoppingCartList总是空的,即使是数据库中的项目。

这是我的测试函数抛出错误:

@Test

public void createAndRetrieveCart(){
    Customer walter = Customer.find.where().eq("email", "test@banananow.com").findUnique();
    Product p1 = Product.find.where().idEq(1).findUnique();
    Product p2 = Product.find.where().idEq(2).findUnique();

    new ShoppingCart(walter, p1, 2).save();
    new ShoppingCart(walter, p2, 3).save();

    if(walter.shoppingCartList.size() < 2){
        assert(false);
    }
    for(ShoppingCart cart : walter.shoppingCartList){
        assertNotNull(cart.product.name);
        assertNotNull(cart.product.price);
        System.out.println(cart.product.name);
        System.out.println(cart.product.price);
        System.out.println(cart.quantity);

    }
}

错误发生在第123行,这是第一个ShoppingCart.save() 奇怪的部分几乎是creditCardList传递的相同代码并且正常工作。这是测试

public void createAndAddCreditCard(){
        Customer walter = Customer.find.where().eq("email", "tester@test.com").findUnique();
        //Date date = new Date(2017, 10, 1);
        //new CreditCard(1234567812345679L, walter, "walter wooodall", date, 21919, 123).save();
        for(CreditCard card : walter.creditCardList){
           System.out.println(card.number);
        }
    }

以下是我的模特:

客户:

@Entity
public class Customer extends Model {

    @Id
    public int id;
    public String email;
    public String password;
    public String name;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="address_id")
    public Address address;
    public double balance;
    @OneToMany(mappedBy = "customer")
    public List<CreditCard> creditCardList;
    @OneToMany(mappedBy = "customer")
    public List<Basket> basketList;
    @OneToMany(mappedBy = "customer")
    public List<ShoppingCart> shoppingCartList;

    public Customer(String email, String password, String name, Address address){
        this.email = email.toLowerCase();
        this.password = password;
        this.name = name.toLowerCase();
        this.address = address;
        this.balance = 0.0;
        //this.creditCardList = new ArrayList<CreditCard>();
        //this.shoppingCartList = new ArrayList<ShoppingCart>();
    }

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

    public static Customer authenticate(String email, String password) {
        return find.where().eq("email", email)
                .eq("password", password).findUnique();
    }

    public static Customer exists(String email) {
        return find.where().eq("email", email).findUnique();
    }

    /*
    public List<CreditCard> getCreditCardList(){
        return CreditCard.find.where().eq("customer_id", this.id).findList();
    }
    */
}

ShopppingCart:

@Entity
@Table(name="shopping_cart")
public class ShoppingCart extends Model{
    @Id
    public int id;
    @ManyToOne
    @JoinColumn(name = "customer_id", insertable = false, updatable = false)
    public Customer customer;
    @ManyToOne
    @JoinColumn(name = "product_id", insertable = false, updatable = false)
    public Product product;
    public int quantity;


    public ShoppingCart(Customer customer, Product product, int quantity){
        this.customer = customer;
        this.product = product;
        this.quantity = quantity;
    }

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


}

产品:

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

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

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

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

    public static List<Product> getTopProducts(){
        String sql = "select * from top_product";
        SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
        List<SqlRow> sqlRows = sqlQuery.findList();
        List<Product> productList = null;
        if(sqlRows != null){
            productList = new LinkedList<Product>();
            for(SqlRow row : sqlRows){
                int id = row.getInteger("id");
                String name = row.getString("name");
                float price = row.getFloat("price");
                String category = row.getString("category");
                String subcategory = row.getString("subcategory");
                String imageUrl = row.getString("image_url");
                String url = row.getString("url");
                String storeId = row.getString("store_id");
                productList.add(new Product(id, name, price, category, subcategory, imageUrl, url, Store.find.byId(storeId)));
            }
        }
        return productList;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", category='" + category + '\'' +
                ", subcategory='" + subcategory + '\'' +
                ", image_url='" + imageUrl + '\'' +
                ", url='" + url + '\'' +
                '}';
    }
}

我的表中有id,customer_id,product_id和数量,FK引用了客户和产品。

其他人有这个问题,知道如何解决?

1 个答案:

答案 0 :(得分:1)

似乎以下行没有读取客户:

Customer walter = Customer.find.where().eq("email", "test@banananow.com").findUnique();

您的第二次测试效果很好,但您在那里通过不同的电子邮件查询客户。因此,请尝试将上一行更改为:

Customer walter = Customer.find.where().eq("email", "tester@test.com").findUnique();

Socond问题是你有:

@JoinColumn(name = "customer_id", insertable = false, updatable = false)
@JoinColumn(name = "product_id", insertable = false, updatable = false)

这就是为什么不保存这些关系的原因。删除这些行。