无法实例化类模型。客户。它必须具有默认构造函数

时间:2014-10-20 16:55:33

标签: java playframework default-constructor

  

[error] play - 无法调用动作,最终得到一个错误:java.lang.RuntimeException:无法实例化类models.Customer。它必须具有默认构造函数

当我使用play framework 2.3.5时,我遇到了这个问题。似乎默认构造函数和我自己编写的构造函数之间存在重写。但是Customer实体扩展了User实体,应该有一个构造函数来管理它。因此,我不知道如何解决它。

Controller.Appllication

package controllers;

import models.Customer;
import models.User;
import play.*;
import play.data.Form;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.mvc.*;
import views.html.*;
import static play.data.Form.form;

public class Application extends Controller {

    //for logging
    public static Logger LOG = new Logger();

    final static Form<Customer> signupForm = form(Customer.class);


    public static Result blank() {
        return ok(signup.render(signupForm));
    }

    public static Result submit(){
        Form<Customer> filledForm = signupForm.bindFromRequest();
        LOG.info(filledForm.toString());
        LOG.info("Username: " + filledForm.field("username").value());

        //instantiate User entity
        Customer created = filledForm.get();
        LOG.info("User:" + created.toString());

        Customer newcus = Customer.create(created.getEmail(), created.getUsername(), created.getPassword());

        session("email", newcus.getEmail());
        LOG.info("sessionUser:" + newcus.getEmail());

        return redirect(
                //return to home page
            routes.Application.welcome()
        );
    }
}   

Model.Customer

import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

import play.db.jpa.JPA;


@Entity
public class Customer extends User{

    protected Customer(String email, String username, String password) {
        super(email, username, password);
    }

    public static Customer create(String email, String username, String password){
        Customer cus = new Customer(password, password, password);
        JPA.em().persist(cus);
        return cus;

    }

    @ManyToMany(cascade = { CascadeType.ALL })
    private Collection<ConcreteCourse> selectedCourses = new ArrayList<ConcreteCourse>();

    @OneToMany(mappedBy = "author", cascade = { CascadeType.ALL })
    private Collection<Review> reviews = new ArrayList<Review>();

}

Model.User     包模型;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

import play.data.format.Formats;
import play.data.validation.Constraints;
import common.BaseModelObject;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class User extends BaseModelObject {

    //
    @Constraints.Required
    @Formats.NonEmpty
    @Column(unique = true)
    public String email;

    @Constraints.Required
    @Formats.NonEmpty
    public String username;

    @Constraints.Required
    @Formats.NonEmpty
    public String password;

    protected User(String email, String username, String password) {
        this.email = email;
        this.username = username;
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

2 个答案:

答案 0 :(得分:3)

上面的CustomerUser类都没有默认构造函数。在使用参数声明自己的构造函数的那一刻,您立即禁用默认构造函数。或者更确切地说,如果您从未声明任何构造函数,Java会自动为您的。

创建一个默认构造函数

您需要为两个类定义默认构造函数。由于您的课程中没有最终字段,因此这应该非常简单。实际上,您也可以保留旧的构造函数(如果它们在您的应用程序中的某个位置有帮助的话)。

public class Customer extends User{
    public Customer() {
    }
}

注意:您需要将默认构造函数设为public。大多数JPA框架所做的是使用Java反射来实例化您的类。他们中的大多数都依赖于你有一个他们可以轻松使用的公共默认构造函数(没有任何参数)(否则他们需要确定传递给构造函数的数据类型)。在他们实例化了类之后,他们使用任何setter或getter方法来配置字段(例如emailusername),除非您的字段是公共的(如您的情况),在这种情况下,这些方法是不需要。

答案 1 :(得分:0)

我也遇到了这个错误。别担心,只需在Customer类中添加默认的无参数构造函数。

public Customer(){

}