Hi Everyone,
I'm running into an issue reconstituting an object from the database using Hibernate. An @Embedded
component is throwing a NullPointerException when it's being accessed for the class' hashCode()
implementation.
The reconstitution is attempting to be done thus:
@Override
public Collection<Web> getWebs() {
Collection<?> dbWebs =
this.sessionFactory.getCurrentSession()
.createQuery("from Web")
.list();
Set<Web> webs = new HashSet<Web>();
for (Object web : dbWebs) {
webs.add((Web) web);
}
return webs;
}
And fails at .list()
.
UPDATE: I isolated the failure point to setting the the Shipment property's fetch strategy to EAGER
. If it's LAZY
the items all come out of the DB fine but I need it to be EAGER
to work with other parts of the app. Further thoughts?
The parent class:
@Entity
@Table(name = "web")
public class Web {
@Id
@GeneratedValue
private Long id;
@Embedded
private WebNumber number;
@Embedded
private IcnRange icnRange;
@ManyToOne(fetch = FetchType.EAGER) //Cannot make this EAGER
@JoinColumn(name = "shipment_id")
private Shipment shipment
...
@Override
public int hashCode() {
int hashcode = 0;
hashcode += this.getIcnRange().hashCode();
hashcode += this.getPublicId().hashCode();
return hashcode;
}
}
IcnRange:
@Embeddable
public class IcnRange implements Comparable<IcnRange>, Serializable {
@Embedded
@AttributeOverride(
name = "number",
column = @Column(
name = "first_icn",
length = ICN.FIELD_LENGTH,
nullable = false))
private ICN firstIcn;
@Embedded
@AttributeOverride(
name = "number",
column = @Column(
name = "last_icn",
length = ICN.FIELD_LENGTH,
nullable = false))
private ICN lastIcn;
...
public IcnRange(final IcnRange icnRange) {
this.firstIcn = new ICN(icnRange.getFirstIcn());
this.lastIcn = new ICN(icnRange.getLastIcn());
}
}
ICN:
@Embeddable
public class ICN implements Comparable<ICN>, Serializable {
@Column(nullable = false, length = FIELD_LENGTH)
private String number;
...
}
WebNumber:
@Embeddable
final class WebNumber implements Serializable {
@Enumerated(EnumType.STRING)
@Column (name = "stock_type", nullable = false, length = StockType.FIELD_LENGTH)
private StockType stockType;
@Embedded
@AttributeOverride (
name = "number",
column =
@Column (
name = "pallet",
nullable = false,
length = Pallet.FIELD_LENGTH))
private Pallet pallet;
@Enumerated(EnumType.STRING)
@Column (name = "pallet_id", nullable = false, length = PalletId.FIELD_LENGTH)
private PalletId palletId;
}
The specific offensive line is in the copy constructor:
public IcnRange(final IcnRange icnRange) {
this.firstIcn = new ICN(icnRange.getFirstIcn());
this.lastIcn = new ICN(icnRange.getLastIcn());
}
It chokes upon calling icnRange.getFirstIcn()
. Further investigation reveals that icnRange
enters the method as null
so for some reason the component is not being reconstituted. Investigation of the DB reveals that none of the fields are null. I'm including WebNumber as if I reverse the hashCode()
method in Web
, it still fails because getPublicId()
, which depends on WebNumber
, returns null
The Full Stack Trace:
java.lang.IllegalArgumentException: Cannot process null arguments.
at jaci.util.ExceptionUtils.illegalNullArgs(ExceptionUtils.java:20)
at jaci.model.check.IcnRange.<init>(IcnRange.java:54)
at jaci.model.web.Web.getIcnRange(Web.java:345)
at jaci.model.web.Web.hashCode(Web.java:255)
at java.util.HashMap.put(HashMap.java:372)
at java.util.HashSet.add(HashSet.java:200)
at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:352)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:260)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:245)
at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:218)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:900)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:888)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.EntityType.resolve(EntityType.java:412)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2228)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
at org.hibernate.loader.Loader.list(Loader.java:2120)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:361)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1148)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at jaci.dao.WebDaoHibernate.getWebs(WebDaoHibernate.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy44.getWebs(Unknown Source)
at jaci.dao.WebDaoIntegrationTest.getWebs_NoCriteria_OneOrMoreWebs(WebDaoIntegrationTest.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Any thoughts for a weary sailor? Thank in advance!