简体   繁体   中英

Java Generic Type with extends and T using Hibernate

I have a simple interface like this.

public interface EntityClass
{    
    public void setId(final Integer id);    
    public Integer getId();    
}

and a class

public Student implements EntityClass

I am trying to code a class which uses a generic type T but still is a instanceof EntityClass a EntityClass subclass something like this.

public abstract class CustomizableQueriesForClazzAndFields<T extends EntityClass>

That's is the project inside that class i want a method like this.

public List<T>getMultipleClazzWithFields(final String ...fields){return of(genericType).retrieve(fields);}

private MyCriteria of(final Class<? extends EntityClass>applyToClazz){........}

MyCriteria is a wrapper over org.hibernate.Criteria.

And in my implementation would do something like this.

public final class TestCustom extends CustomizableQueriesForClazzAndFields<Student>
{
    public static void main(String[] args) 
   {
       final TestCustom clazz = new TestCustom();
       final List<Student>a=clazz.getMultipleClazzWithFields("id","name","phone");
       a.stream().forEach(clazz::consumer);
   }     
 }

Doing this code i would like to be represent it like this using generics.

public List<Student>getMultipleClazzWithFields(final String ...fields){return of(Student.class).retrieve(fields);}

But i dont know how to represent this or if it's possible.

public List<T>getMultipleClazzWithFields(final String ...fields){return of(genericType).retrieve(fields);}

Which genericType should be represent it as Student the same Student as

public final class TestCustom extends CustomizableQueriesForClazzAndFields<Student>

Or represent it as

public final class TestCustom extends CustomizableQueriesForClazzAndFields<School>

And would do something like

public List<School>getMultipleClazzWithFields(final String ...fields){return of(School.class).retrieve(fields);}

Because i was diving like this

public List<T>getMultipleClazzWithFields(final String ...fields){return of(T).retrieve(fields);}

But the compiler kicks me and says.

cannot find symbol
symbol:   variable T
location: class CustomizableQueriesForClazzAndFields<T>
where T is a type-variable:
T extends EntityClass declared in class CustomizableQueriesForClazzAndFields
----
(Alt-Enter shows hints)

I also try

public abstract class CustomizableQueriesForClazzAndFields<Class<T extends EntityClass>>

But says.

> expected
----
(Alt-Enter shows hints)

Or how i can accomplish my desire code.. any workaorund.

Because ia kind annoying passing as parameter.

UPDATE

All i wanna to do is pass a SubClass of EntityClass and creates.

session.createCriteria(genericType);

As well gives me the List but i dont know if it's possible to catch or capture the generic type pass CustomizableQueriesForClazzAndFields<Student> and passed to of() method which is who created the org.hibernate.Criteria object i cannot pass only a T value because in my graph would like to be a subclass of EntityClass a not just a raw T value.

I need to catch or capture

CustomizableQueriesForClazzAndFields<Student> 

Student generic type.

If this possible or i am dreaming sorry by my poor english.

Thank a lot and best regards from Venezuela..

Approach 1:

I'm not sure I fully understand your question but I have the feeling you want something like this:

public abstract class CustomizableQueriesForClazzAndFields<T extends EntityClass> {
  public List<T> getMultipleClazzWithFields(final Class<T> clazz, final String ...fields){
    return of(clazz).retrieve(fields);
  }

  private MyCriteria of(final Class<T> applyToClazz) {
     ...
  }
}

The compiler can't create/retrieve an instance of T at runtime just from inferred data, hence you have to pass that information somehow eg as a parameter:

List<Student> l = getMultipleClazzWithFields(Student.class, "field1", "field2");

Approach 2:

Instead of passing Class<T> as a parameter you could also create subclasses for every T , eg class StudentQueries extends CustomizableQueriesForClazzAndFields<Student> , and then use reflection to find out the type of T . Please note though, that this would only work for sublcasses that define the concrete type of T .

Which approach is better depends on your needs but if it's just for that query I'd pass the class of the entity as a call parameter and skip all those subclasses that would be needed otherwise.

Update : if you want to implement the second approach (subclasses) have a look here for some code on how to use reflection to look up the type of T : http://www.artima.com/weblogs/viewpost.jsp?thread=208860

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM