java - 无法实例化类 models.Customer。它必须有一个默认构造函数

标签 java playframework default-constructor

[error] play - Cannot invoke the action, eventually got an error: java.lang.RuntimeException: Cannot instantiate class models.Customer. It must have a default constructor

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

Controller.Application

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()
        );
    }
}   

模型.客户

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>();

}

模型.用户 封装模型;

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;
    }

}

最佳答案

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

您需要为这两个类定义一个默认构造函数。由于您的类中没有 final 字段,因此这应该相当简单。事实上,您也可以保留旧的构造函数(如果它们在您的应用中的某个地方有帮助的话)。

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

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

关于java - 无法实例化类 models.Customer。它必须有一个默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26470933/

相关文章:

java - 使用 Instrumentation 记录未处理的异常

java - Urban Airship Android addTag 响应?

java - mongo模板查询文档数组

c# - 正确使用这个。在类构造函数中

c++ - 继承的 protected 默认构造函数不可访问

java - 两个 JList 模型不使用所有数据

scala - 用于使用 Play/SBT 进行自定义测试配置的 javaOptions

java - Play Framework 2.1 IDE 设置

mysql - 在 Model 类中设置关系不会在 playFramework 中创建数据库表条目

c# - 自定义控件构造函数