Probably some lazy loading which hits you?
When does the EntityManager get closed? You do not touch anything from the 
entity before the EntityManager gets closed? In that case this might be 
perfectly covered by the JPA spec.

Which form of enhancement do you use? build-time, classtransformer via 
javaagent or subclassing?
Can you check in the debugger which StateManager is in the entity instance? 
DetachStateManager or StateManagerImpl?

LieGrue,
strub


> Am 04.07.2015 um 11:07 schrieb Jim Talbut <jtal...@spudsoft.co.uk>:
> 
> Hi,
> 
> I have this class:
> @Transactional
> @Component
> public class ProjectTransactionsImpl implements ProjectTransactions {
> 
>    @SuppressWarnings("constantname")
>    private static final Logger logger = 
> LoggerFactory.getLogger(ProjectTransactionsImpl.class);
> 
>    @Autowired
>    private ProviderService providerService;
> 
>    @Override
>    public Provider findProvider(String providerId) {
>        Provider provider = providerService.find(providerId);
>        logger.debug("Returning: {}", provider.getClass());
>        return provider;
>    }
> }
> 
> And a unit test calling it like this:
> @RunWith(SpringJUnit4ClassRunner.class)
> @ContextConfiguration(locations = {"file:src/test/resources/testContext.xml"})
> @TransactionConfiguration(transactionManager = "transactionManager", 
> defaultRollback = false)
> public class MigrateProjects extends AbstractMigrationClass {
> 
>    private static final Logger logger = 
> LoggerFactory.getLogger(MigrateProjects.class);
> 
>    @Autowired
>    private ProjectTransactions trans;
> 
>    private int projectsAdded = 0;
>    private final Map<String, Integer> providerProjectCountBefore = new 
> HashMap<>();
> 
>    @Test
>    public void test1() throws Exception {
>        logger.debug("Getting provider");
>        Provider provider = trans.findProvider("GTI");
>        logger.debug("Returned: {}", provider);
>    }
> }
> 
> Using OpenJPA 2.4.0 with Spring 4.1.7.RELEASE.
> 
> The log shows this:
> 09:56:52.913 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(54) MigrateProjects::test1] Getting provider
> 09:56:52.914 [main] DEBUG c.g.e.a.t.ProjectTransactionsImpl - 
> [ProjectTransactionsImpl.java(41) ProjectTransactionsImpl::findProvider] 
> Returning: class com.groupgti.esb.assessments.model.jpaimpl.ProviderImpl
> 09:56:52.915 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(56) MigrateProjects::test1] Returned: null
> 
> So I had an object in the call to findProvider, but it has become null by the 
> time if gets to the call site.
> If I change the logging line in findProvider to:
>        logger.debug("Returning: {}", provider);
> Then I get this:
> 09:59:44.234 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(54) MigrateProjects::test1] Getting provider
> 09:59:44.235 [main] DEBUG c.g.e.a.t.ProjectTransactionsImpl - 
> [ProjectTransactionsImpl.java(41) ProjectTransactionsImpl::findProvider] 
> Returning: ProviderImpl{id=8, providerId=GTI, projects=20, 
> maintenanceWindows=0, textBlocks=0}
> 09:59:44.238 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(56) MigrateProjects::test1] Returned: 
> ProviderImpl{id=8, providerId=GTI, projects=20, maintenanceWindows=0, 
> textBlocks=0}
> 
> So if I log the object it gets output, but if I don't I get null.
> I can't debug this because the act of debugging makes it work!
> 
> If I change the logging line to:
>        provider.getProjects();
> Just to prove I've really got an object and to ensure that a collection gets 
> loaded.
> Then I get:
> 10:01:37.101 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(54) MigrateProjects::test1] Getting provider
> 10:01:37.109 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(56) MigrateProjects::test1] Returned: null
> 
> If I change the logging line to:
>        provider.toString();
> Then it works again:
> 10:03:09.843 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(54) MigrateProjects::test1] Getting provider
> 10:03:09.847 [main] DEBUG c.g.e.a.t.MigrateProjects - 
> [MigrateProjects.java(56) MigrateProjects::test1] Returned: 
> ProviderImpl{id=8, providerId=GTI, projects=20, maintenanceWindows=0, 
> textBlocks=0}
> 
> So something in toString seems to be making it work.
> The toString() implementation isn't very complicated:
>    @Override
>    public String toString() {
>        try {
>            return "ProviderImpl{" + "id=" + id + ", providerId=" + providerId 
> + ", projects=" + projects.size() + ", maintenanceWindows=" + 
> maintenanceWindows.size()
>                    + ", textBlocks=" + textBlocks.size() + '}';
>        } catch (NullPointerException ex) {
>            return null;
>        }
>    }
> It's not hitting any NPE because it is returning a correct string.
> 
> Can anyone shed some light on what is happening here?
> Or suggest some approach I can take to debug it?
> 
> Thanks
> 
> Jim
> 

Reply via email to