1

I'm trying to upgrade an application to use the latest version of Spring. It currently uses Spring 3.0.7 and Hibernate 3.5.6. I'm able to successfully upgrade it to Spring 3.2.8, but if I upgrade it to Spring 4, I get compilation errors like the following:

[ERROR] /Users/mraible/dev/foo-upgrades/foo-core/src/main/java/com/company/foo/dao/companydb/impl/hibernate/InFaxDAOImpl.java:[71,82] incompatible types
[ERROR] required: java.util.List<com.company.foo.common.domain.FaxPage>
[ERROR] found:    java.util.List<capture#49 of ?>

The method call looks like the following:

List<FaxPage> faxPages = getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, hqlParams, values);

I can fix the compilation error by casting to the list type, but that doesn't seem right.

List<FaxPage> faxPages = (List<FaxPage>) getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, hqlParams, values);

What is it about Spring 4 that breaks HibernateDaoSupport so it's not backwards compatible?

Matt Raible
  • 8,187
  • 9
  • 61
  • 120
  • Which version of Spring 4? There is [an issue](https://jira.spring.io/browse/SPR-11402) related to the return types in HibernateTemplate in Spring 4 that has been addressed in Spring 4.0.2. – Andrei Stefan Apr 22 '14 at 08:37
  • I'm using Spring 4.0.3. – Matt Raible Apr 22 '14 at 13:47
  • Your original code has probably a `@SuppressWarnings("unchecked")` somewhere because the orignal return type was a _raw_ `List`. The raw list has the "advantage" of allowing you to build such construct that only leads to a compiler warning. The implicit cast you have to do know is because the signature is now `List>`. I agree this is unfortunate but keeping a raw list isn't such a good option either. – Stephane Nicoll Apr 22 '14 at 14:02
  • You are correct Stéphane - there is a @SuppressWarnings("unchecked") on the methods. Is the recommended refactoring to use casting? – Matt Raible Apr 22 '14 at 14:10
  • And if you have Mockito mocks, just add `Mockito.>when(...)` on your test fixtures. – Zero Distraction Sep 10 '14 at 07:57
  • Did updating your hibernate rectify this issue, or did you need to make the code changes throughout your project? – Paul Apr 17 '15 at 09:17

1 Answers1

3

This is because the Spring framework used to return a raw list declaration and that raw list declaration basically allows you to declare any type you want. If you do that, the compiler will issue a warning that can be "ignored" with a @SuppressWarnings("unchecked") declaration.

While backward compatibility could have been provided for this, many references suggest to never use raw lists in "new code".

Quote of the Java Language Specification

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

This thread is a good summary of that matter.

While I can certainly understand the benefit of what you used to be able to do, I would advise you to update your code as you did, yes: you were doing an implicit cast previously anyway.

Community
  • 1
  • 1
Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89