-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 
Author Message
 Post subject: Java 1.5 Generics unchecked conversion warning
PostPosted: Mon Feb 28, 2005 2:31 am 
Newbie

Joined: Mon Feb 28, 2005 2:10 am
Posts: 5
Using:
hibernate version 2
jdk 1.5.0_01 (in Eclipse version 3.1 - stable build)

I am getting a compile time warning when I retrieve a List of objects through hibernate and try to cast it to a generic List

ie.
Code:
public List<foo> getObjects() {
   List<foo> objects = null;
   try {
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        try {
            List returnList = session.find("from " + foo.class.getName());

            //This line is throwing a warning suggesting: "The expression of type List needs unchecked conversion to conform to List<foo>"
            objects = Collections.checkedList(returnList, foo.class);   
        } finally {
            tx.commit();
            HibernateUtil.closeSession();
        }
    } catch (HibernateException he) {}
    return objects;
}


If I change to:
objects = (List<foo>) session.find("from " + foo.class.getName());

the warning becomes:
"The Cast from List to List<foo> is actually checking against the erased type List"

Reference:
http://java.sun.com/j2se/1.5.0/docs/gui ... erics.html

Can anyone help me write this code to eliminate the warning?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 28, 2005 10:00 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
I can't think of any way to eliminate the warning, besides turning it off in the compiler :)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 13, 2005 2:40 pm 
Newbie

Joined: Wed Apr 13, 2005 2:32 pm
Posts: 3
Location: Ottawa, ON, Canada
Here is the best I could do. If someone has suggestions on how to improve it, please post them. thanks

Code:
  static final List<Terminal> EMPTY_LIST =
    Collections.unmodifiableList(new LinkedList<Terminal>());

.....

  public synchronized List<Terminal> getAllBeans(final int hints)
    throws DataException, BeanException, HibernateException
  {
    Logger log = Logger.getLogger( LOGGER_ID );
    log.entering( CNAME, "getAllBeans", hints );

    Session ses = allocWorkSession();
    try {
      Query qry = ses.getNamedQuery( "Terminal.all" );
      List<Terminal> res = toList(qry.list());
      log.exiting( CNAME, "getAllBeans", res );
      return res;
    }
    finally { freeWorkSession(); }
  }

....

                                // Utilities ---------------------------------

  /** Shallow type-cast copy. */
  public static List<Terminal> toList(final Collection<?> beans)
  {
    if ( beans == null )  return null;
    if ( beans.isEmpty())  return EMPTY_LIST;

    int cnt = beans.size();
    Terminal arr[] = new Terminal[cnt];
    arr = (Terminal[]) beans.toArray(arr);
    return Arrays.asList(arr);
  }


The penalty is alloc of 2 arrays:
1) arr in the utility
2) array backing the new list

There are also a couple of memcpys inside of array's code.
For small/medium size collections the overhead should be minimal. For larger arrays it could be a problem.

Long term I expect a more suitable solution from Sun in JDK 1.6


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 13, 2005 8:33 pm 
Newbie

Joined: Mon Feb 28, 2005 2:10 am
Posts: 5
I am told that I should be using SuppressWarnings
ie.
Code:
@SuppressWarnings(value={"unchecked"}) // although this isn't currently implemented, in the future it will supress
public List<foo> getObjects() {
   ...


However, I dont think this annotation is properly supported yet in my development environment (eclipse/1.5 as specified in earlier post) and I am still getting the warning.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 13, 2005 8:51 pm 
Newbie

Joined: Mon Feb 28, 2005 2:10 am
Posts: 5
also, the method should apparently use the checkedList method from java.util.Collections:
ie.
Code:
return Collections.checkedList(objects, foo.class);


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2005 11:15 am 
Newbie

Joined: Wed Apr 13, 2005 2:32 pm
Posts: 3
Location: Ottawa, ON, Canada
jkotchoff wrote:
also, the method should apparently use the checkedList method from java.util.Collections:
ie.
Code:
return Collections.checkedList(objects, foo.class);


I don't think that it is necessary. The copying of list elments into type specific array in effect performs type checking of all elements. Once it is successful we are guaranteed that all array elements are of the proper type and checked collection is not needed. You could convert the exception type if you like, such as:

Code:
    try {
      arr = (AALanguage[]) beans.toArray(arr);
      return Arrays.asList(arr);
    }
    catch (ArrayStoreException e) {
      ClassCastException e2 = new ClassCastException("Failed to convert type to AALanguage!");
      e2.initCause(e);
      throw e2;
    }


The new version:
Code:
  /** Shallow type-cast copy. */
  public static List<AALanguage> toList(final List<?> beans)
    throws ClassCastException
  {
    if ( beans == null )  return null;
    if ( beans.isEmpty())  return EMPTY_LIST;

    int cnt = beans.size();
    AALanguage arr[] = new AALanguage[cnt];
    try {
      arr = (AALanguage[]) beans.toArray(arr);
      return Arrays.asList(arr);
    }
    catch (ArrayStoreException e) {
      ClassCastException e2 = new ClassCastException("Failed to convert type to AALanguage!");
      e2.initCause(e);
      throw e2;
    }
  }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 14, 2005 11:21 am 
Newbie

Joined: Wed Apr 13, 2005 2:32 pm
Posts: 3
Location: Ottawa, ON, Canada
jkotchoff wrote:
I am told that I should be using SuppressWarnings
ie.
Code:
@SuppressWarnings(value={"unchecked"}) // although this isn't currently implemented, in the future it will supress
public List<foo> getObjects() {
   ...


However, I dont think this annotation is properly supported yet in my development environment (eclipse/1.5 as specified in earlier post) and I am still getting the warning.


Ah yes, that is the solution I have been looking for. Excellent!
Indeed, doesn't seem to be supported/implemented yet properly, but should work in sunsequent releases. I can wait.

To conclude, when the source is trustworthy I will typecast and supress the warnings:
Code:
  @SuppressWarnings(value={"unchecked"})
  public synchronized List<AALanguage> getAllBeans(final int hints)
....
      List<AALanguage> res = (List<AALanguage>) qry.list();


Otherwise if I don't trust the collection source I will use the function above to convert safely.
Unless I am missing something, the checked collections serve a slightly different purpose.

Thanks for the info :)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 11, 2005 5:39 am 
Newbie

Joined: Sat Jun 11, 2005 5:27 am
Posts: 11
I'm told, on the java forums, that @SuppressWarnings is on the bugs database and scheduled for implementation in the next release (Mustang). Certainly much needed.

Still, it's a fudge and hibernate itself needs to go generic. find would need an extra argument, I think (the class of the entities to be retrieved). Criteria would work better with generics, since you could make it a generified class.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 11, 2005 9:44 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
And force users onto JDK5? No thanks...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 24, 2005 4:36 am 
Newbie

Joined: Sat Jun 11, 2005 5:27 am
Posts: 11
steve wrote:
And force users onto JDK5? No thanks...


I think it's going to have to happen eventually (even if it means maintaining two versions). Perhaps new generic Criteria classes as part of the Annotations extensions. Annotations is going to be just too useful to ignore, and also requires JDK5

In the meantime what I've done is to write a wrapper class for Criteria which allows all the warnings to be concentrated in that one class.

Code:
/**
* <p>Generisised wrapper for criteria. Hopefully this will put all
* the unavoidable unchecked warnings into this one class.<p>
* @author malcolmm
*/
@SuppressWarnings("unchecked")
public class GenericCriteria<T> {
    Criteria crit;
   
    /** Creates a new instance of GenericCriteria
     * @param crit Criteria to wrap
     */
    public GenericCriteria(Criteria crit) {
        this.crit = crit;
    }
   
   
    /**
     * Create criteria from session
     * @param session The hibernate session
     * @param cls The class of the entities to be retrieved
     */
    public GenericCriteria(Session session, Class<T> cls) {
        this(session.createCriteria(cls));
    }
    /**
     * Add a restriction to the criteria
     * @param filter The criterion to apply
     */
    public void add(Criterion filter) {
        crit.add(filter);
    }
   
    /**
     * Impose an ordering on the criterion query.
     * @param order The order to impose
     */
    public void addOrder(Order order) {
        crit.addOrder(order);
    }
    /**
     * Get the results
     *
     */
    public java.util.List<T> list() throws HibernateException {
        return crit.list();
    }
   
    public T uniqueResult() {
        return (T)crit.uniqueResult();
    }
   
    public static <E> GenericCriteria<E> create(Session session, Class<E> targetClass) {
        return new GenericCriteria<E>(session,  targetClass);
    }
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 23, 2007 10:05 pm 
Newbie

Joined: Tue Jan 23, 2007 9:58 pm
Posts: 1
Wouldn't it be reasonable to expect that Hibernate starts to support generics properly some day, rather then suggesting to pretend that the problem does not exist through Suppress annotations technique?


Top
 Profile  
 
 Post subject: Typesafe Criteria Wrapper Class
PostPosted: Thu Feb 05, 2009 1:45 pm 
Beginner
Beginner

Joined: Mon Jul 28, 2008 4:36 pm
Posts: 24
soupdragon wrote:
In the meantime what I've done is to write a wrapper class for Criteria which allows all the warnings to be concentrated in that one class...


That's awesome! Thanks! Where's my button to give you a thumbs up or a +1 or something?

I especially like the static create() method. I'm going to make the constructor private and only expose the static factory method.

Great tip. I would have spent longer than I care to admit thinking about this without your code.

_________________
_____________________
-Glen


Top
 Profile  
 
 Post subject: Re: Java 1.5 Generics unchecked conversion warning
PostPosted: Mon Jul 12, 2010 6:14 am 
Newbie

Joined: Thu Aug 28, 2008 5:26 am
Posts: 1
Try this one

public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
List<T> r = new ArrayList<T>(c.size());
for(Object o: c)
r.add(clazz.cast(o));
return r;
}


Top
 Profile  
 
 Post subject: Re: Java 1.5 Generics unchecked conversion warning
PostPosted: Mon Jul 12, 2010 8:51 am 
Newbie

Joined: Mon Nov 30, 2009 2:19 pm
Posts: 7
I really like the GenericList approach. To be able to use the createCriteria method of the wrapped criteria I introduced the following method:

Code:

   public <K> GenericCriteria<K> createCriteria(String associationPath, Class<K> targetClass) {
      return new GenericCriteria(this.crit.createCriteria(associationPath));
   }


It shoud be an ease to add the missing other createCriteria methods with different parameters...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.