2014-10-20 23 views
1

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

} 
+0

在java中,如果您編寫任何其他構造函數,則不需要顯式地寫入args構造函數。只有在沒有其他構造函數的情況下才能使用arg構造函數。您還需要在您的Customer類中編寫無參數構造函數。從那個空的構造函數中,如果需要的話,你可以在super上調用父構造函數。 – Jimmy 2014-10-20 16:58:16

回答

3

既不Customer也不User類以上具有默認構造函數。當你用參數聲明你自己的構造函數時,你立即禁用默認的構造函數。或者說,如果你從不聲明任何構造函數,Java會自動爲你創建一個默認的構造函數。

您將需要爲兩個類定義默認構造函數。由於您的課程中沒有最終字段,因此這應該相當簡單。事實上,你可以保留你的舊構造函數(如果它們在你的應用程序的某個地方有幫助)。

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

注:你需要有默認的構造函數公衆。大多數JPA框架所做的是使用Java反射來實例化您的類。他們中的大多數都依賴於你有一個公共的默認構造函數(沒有任何參數),他們可以很容易地使用(否則他們需要確定傳遞給你的構造函數的數據類型)。在他們實例化類後,他們使用任何setter或getter方法來配置字段(例如email,username),除非您的字段是公開的(如您的情況),在這種情況下不需要此類方法。

+0

謝謝,它工作。我不應該在其中添加參數構造函數 – 2014-10-20 17:18:21

0

我也遇到了這個錯誤。別擔心,只需在您的Customer類中添加默認的無參數構造函數即可。

public Customer(){ 

} 
相關問題