Java multiplay level inheritance of abstract java

2019-08-23 06:57发布

问题:

Hey according to that post: link I've made my models inheritance structure.

But I would like to expand it adding two generic models that will extend primary GenericModel and add some parameters and functionality. Those class will be called GenericDictionary and GenericAudit. Those class will be extended by entities.

Here is my new structure: GenericModel (contain id, create date)

public abstract class Generic<T extends Generic> {

-GenericDictionary (contains GenericModel and adds name parameter and getters/setters)

public abstract class GenericDictionary<T extends Generic<T extends GenericDictionary>> {

And class that extends GenericDictionary:

public class InconsistencyOrigin extends GenericDictionary<InconsistencyOrigin> {

-GenericAudit (contains GenericModel and adds other parameters- dosnt contain name!!!)

When I am trying to do this I am getting an error:

 error: type argument InconsistencyOrigin is not within bounds of type-variable T 

My classes once more:

package models;

import java.lang.reflect.ParameterizedType;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.NoResultException;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.TypedQuery;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import controllers.common.Index;
import play.Logger;
import play.data.validation.Constraints;
import play.db.jpa.JPA;

@MappedSuperclass
public abstract class Generic<T extends Generic> {
    @Transient
    private Class<T> entityClass;
    Generic() {
        entityClass = ((Class) ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
    }
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    @ManyToOne(cascade = CascadeType.MERGE)
    @Constraints.Required
    public User creationUser;
    @Constraints.Required
    public String creationDate = Index.getDate(null);
    @Constraints.Required
    public String updateDate = Index.getDate(null);

    public User getCreationUser() {return creationUser;}
    public void setCreationUser(User user) {this.creationUser = user;}
    public void setCreationUser() {this.creationUser = User.getCurrentUser();}
    public String getCreationDate() {return creationDate;}
    public void setCreationDate(String creationDate) {this.creationDate = creationDate;}
    public String getUpdateDate() {return updateDate;}
    public void setUpdateDate(String updateDate) {this.updateDate = updateDate;}
    public T getBy(Long id) {
        return JPA.em().find(entityClass, id);
    }
    public List<T> getByUser_id(Long id) {
        List<T> entities = new ArrayList<T>();
        TypedQuery<T> query = JPA.em().createQuery("SELECT r FROM " + entityClass.getSimpleName() + " r WHERE r.user.id != :user_id", entityClass).setParameter("user_id", id);
        try {
            entities = query.getResultList();
        } catch (NoResultException e) {
            entities = null;
        }
        return entities;
    }


    @PrePersist
    public void prePersist() {
        Logger.warn(this.toString());
        setCreationDate(Index.getDate(null));
        preUpdate();
    }

    @PreUpdate
    public void preUpdate() {
        setUpdateDate(Index.getDate(null));
    }
    public void toDataBase() {
        JPA.em().persist(this);
    }
    public void update() {
        JPA.em().merge(this);
    }

    /**
     *  A Generic toString method that can be used in any class.
     *  uses reflection to dynamically print java class field
     *  values one line at a time.
     *  requires the Apache Commons ToStringBuilder class. 
     */
    public String toString() {
      return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }
}




package models;

import play.data.validation.Constraints;

public abstract class GenericDictionary<T extends Generic<T>> {

    @Constraints.Required
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


package models;

import javax.persistence.Entity;
import javax.persistence.Table;

import play.data.validation.Constraints;

@Entity
@Table(name="intranet___InconsistencyOrigin")
public class InconsistencyOrigin extends GenericDictionary<InconsistencyOrigin> {

}

回答1:

You specify T as extends Generic and supply InconsistencyOrigin for T, so InconsistencyOrigin would have to extend Generic, what it does not.