问题
Hallo all.
I'm trying to map an association one-to-many to an entity that is mappes with @Inheritance(strategy=InheritanceType.JOINED)
....
@ManyToMany
@JoinTable(name = "S_MC_CC_CONTRATTIRAPPORTI",
joinColumns = @JoinColumn(name = "COD_MULTICHANNELID"),
inverseJoinColumns = @JoinColumn(name = "COD_RAPPORTO")
)
private Collection<Rapporto> rapporti;
...
@Entity
@Table(name = "S_MC_CC_RAPPORTI")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="COD_TIPORAPPORTO")
public abstract class Rapporto implements Serializable {
THe problem is that I receive this exception Exception Description: Missing class for indicator field value [1] of type [class java.lang.String].
I think that JPA tries to identify a DiscriminatorValue for the class. I would like to load all the Objects that extend the super class.
Is it possible?
More information: this is the owner of the association
@Entity
@Table(name = "S_MC_CC_CONTRATTI")
public class Contratto implements Serializable {
@Id
@Column(name = "COD_MULTICHANNELID")
private String multichannelId;
@ManyToMany()
@JoinTable(name = "S_MC_CC_CONTRATTIRAPPORTI", joinColumns = @JoinColumn(name = "COD_MULTICHANNELID"), inverseJoinColumns = @JoinColumn(name = "COD_RAPPORTO"))
private Collection<Rapporto> rapporti;
This is the abstract class of the many-to-many association
@Entity
@Table(name = "S_MC_CC_RAPPORTI")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="COD_TIPORAPPORTO")
public abstract class Rapporto implements Serializable {
private static final long serialVersionUID = -5567166522882040440L;
@Id
@Column(name = "COD_RAPPORTO")
protected Long codiceRapporto;
And these are two subclasses:
@Entity
@Table(name="S_MC_CC_CCCLIENTI")
@DiscriminatorValue("1 ")
public class ContoCorrente extends Rapporto {
private static final long serialVersionUID = -3380622649760983262L;
@Column(name = "DESC_DIVISA")
private String divisa;
@Entity
@Table(name = "S_MC_CC_RAPPORTI")
@DiscriminatorValue("6 ")
public class NumeroPortafoglioEstero extends Rapporto {
private static final long serialVersionUID = 6869743707936663970L;
/**
* @param filiale
* @param categoria
* @param conto
*/
public NumeroPortafoglioEstero(Filiale filiale, String categoria, String conto) {
super(filiale, categoria, conto);
}
This is the exception:
Local Exception Stack:
Exception [EclipseLink-43] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [1] of type [class java.lang.String].
Descriptor: RelationalDescriptor(it.alten.intesasanpaolo.contratto.domain.core.rapporto.Rapporto --> [DatabaseTable(S_MC_CC_RAPPORTI)])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:921)
at org.eclipse.persistence.descriptors.InheritancePolicy.classFromValue(InheritancePolicy.java:355)
at org.eclipse.persistence.descriptors.InheritancePolicy.classFromRow(InheritancePolicy.java:342)
at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingDefaultMultipleTableSubclassRead(InheritancePolicy.java:1303)
at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingMultipleTableSubclassRead(InheritancePolicy.java:1402)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2493)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:407)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1076)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:740)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1036)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:380)
at org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:2392)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1291)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1273)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:96)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:86)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:83)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:160)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:220)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:83)
at org.eclipse.persistence.indirection.IndirectList.buildDelegate(IndirectList.java:237)
at org.eclipse.persistence.indirection.IndirectList.getDelegate(IndirectList.java:398)
at org.eclipse.persistence.indirection.IndirectList.toArray(IndirectList.java:741)
at it.alten.intesasanpaolo.contratto.domain.core.anagrafica.Contratto.toString(Contratto.java:262)
at java.lang.String.valueOf(String.java:2827)
at java.io.PrintStream.println(PrintStream.java:771)
at it.alten.intesasanpaolo.contratto.dao.core.anagrafica.TestContrattoDaoJpaImpl.testGetItemByID(TestContrattoDaoJpaImpl.java:99)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
Kind regards Massimo
回答1:
Each entity in the inheritance hierarchy must be a class that is annotated with @Entity
and has a @DiscriminatorValue
回答2:
According to the EclipseLink documentation (see), this exception occurs when the class with particular discriminator value can't be found in the inheritance hierarchy.
Note that the error message shows discriminator value as 1
, whereas in @DiscriminatorValue
it's specified as "1 "
. I think this extra space causes a problem - either this space is stripped when loading value from the database, or old values in the database have discriminators without spaces.
回答3:
I made changes to the @DiscriminatorValue: now the super class defines: @DiscriminatorColumn(name="COD_TIPORAPPORTO", discriminatorType=DiscriminatorType.STRING, length=2)
and the relatives subclasses:@DiscriminatorValue("1")
.
Now I receive no more exceptions, but the queries generated to get the data do not work: here is an example of what is generated:
[EL Fine]: 2011-01-14 19:29:53.312--ServerSession(5230193)--Connection(5612344)--Thread(Thread[main,5,main])--SELECT t0.COD_RAPPORTO, t0.COD_TIPORAPPORTO, t0.COD_MATRICOLAGESTORE, t0.FLAG_RENDICONTAZIONE, t0.COD_CATEGORIA, t0.COD_STATORAPPORTO, t0.FLAG_SB_ATTIVO, t0.COD_GESTORE, t0.TIMESTAMP_AGGIORNAMENTO, t0.DESC_ATTRIBUTO, t0.NUM_RAPPORTO, t0.COD_NSG, t0.COD_ABI, t0.DEN_FILIALE, t1.COD_RAPPORTO, t1.COD_CIN, t1.DESC_DIVISA, t1.COD_CAB, t1.COD_IBAN, t1.COD_CHD, t1.COD_NAZIONE, t1.COD_SERVIZIO FROM S_MC_CC_RAPPORTI t0, S_MC_CC_CONTRATTIRAPPORTI t2, S_MC_CC_CCCLIENTI t1 WHERE (((t2.COD_MULTICHANNELID = ?) AND (t0.COD_RAPPORTO = t2.COD_RAPPORTO)) AND ((t1.COD_RAPPORTO = t0.COD_RAPPORTO) AND (t0.COD_TIPORAPPORTO = ?)))
bind => [01025640171576493, 1]
In effect the query posted via Toad works fine. It seems that the queries to load all the data are working but in effect I cannot see the association valued.
Kind regards to all...
来源:https://stackoverflow.com/questions/4693948/jpa-one-to-many-association-to-an-entity-with-inheritancestrategy-inheritancet