Issue 1:
Don Ngo opened SPR-5138 and commented

Consider the following example:

********** The dependency class

public class Dependency {

@Override

public String toString() {

return "Dependency bean";

}

}

********** The parent domain class

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Configurable;

@Configurable

public class Parent {

@Resource

protected Dependency dependency;

}

********** The child domain class

public class Child extends Parent {

}

********** The context file (context.xml)

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<!-- Switch on the load-time weaving -->
<context:load-time-weaver />

<!-- Apply dependency injection	to non-managed classes annotated with the @Configurable -->
<context:spring-configured />

<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />

<bean id="dependency" class="Dependency" />

</beans>

Now the problem... The dependency injection works fine with the domain objects are created like this:

Parent bean = new Parent();

or this:

Child bean = new Child();

However, it will fail with the following statement (ie. the dependency field will be null (not injected) :

Parent bean = new Child();

Also, I've found that if the following statements are combined, it will fail too:

Parent bean = new Parent();
Parent bean2 = new Child();

Below are some test cases to demonstrate this problem:

******** Demonstrate successful injection

import static org.junit.Assert.assertNotNull;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:context.xml" })

public final class PassTest {

@Test

public final void case1() {

Parent bean = new Parent();

assertNotNull(bean.dependency);

}

@Test
public final void case2() {
Child bean = new Child();
assertNotNull(bean.dependency);
}

}

******** Demonstrate injection failure

import static org.junit.Assert.assertNotNull;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:context.xml" })

public final class FailTest {

@Test

public final void case3() {

Parent bean = new Child();

assertNotNull(bean.dependency); // Will fail!!! Why??!!!

}

}

Affects: 2.5.5

Issue Links:

#9895 @Configureable doesn't work right ("is duplicated by")

#9638 LTW spring-agent Weaving not performed within Test, if class to be woven is referenced by Generic Variable declaration

5 votes, 8 watchers

Issue 2:
David Hewitt opened SPR-2697 and commented

Just upgraded from 2.0-RC2 to 2.0-Final. The refactoring of LocalSessionFactoryBean to introduce an Abstract baseclass seems to have broken the call to updateDatabaseSchema on initialisation. This means that setting schemaUpdate to true always causes a failure on startup.

Previously the SessionFactory was created entirely within the afterPropertiesSet method, at the end of which updateDatabaseSchema was called.

However, now the behaviour is as follows:

AbstractSessionFactoryBean:

public void afterPropertiesSet() throws Exception {

SessionFactory rawSf = buildSessionFactory();

this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);

}

LocalSessionFactoryBean:

protected SessionFactory buildSessionFactory() throws Exception {

SessionFactory sf = null;

...

// Execute schema update if requested.
if (this.schemaUpdate) {
updateDatabaseSchema();
}

return sf;
}

LocalSessionFactoryBean:

public void updateDatabaseSchema() throws DataAccessException {

logger.info("Updating database schema for Hibernate SessionFactory");

HibernateTemplate hibernateTemplate = new HibernateTemplate(getSessionFactory());

...

}

AbstractSessionFactoryBean:

protected final SessionFactory getSessionFactory() {

if (this.sessionFactory == null) {

throw new IllegalStateException("SessionFactory not initialized yet");

}

return this.sessionFactory;

}

At which point an "java.lang.IllegalStateException: SessionFactory not initialized yet" is thrown every time. This is because the call to getSessionFactory() happens as part of updatedDatabaseSchema(), which is called from buildSessionFactory() - which has not yet returned, and therefore the sessionFactory has not been assigned yet. Possibly the sessionFactory "sf" in the buildSessionFactory method should be passed as an argument to updateDatabaseSchema.

Affects: 2.0 final