Community
Participate
Working Groups
>We are getting a ClassCastException in ManagedTypeImpl because there is a restriction on containers of MapAttributeTypes to Entity and MappedSuperclass types. The MapAttribute constructor calls the superclass PluralAttribute which expects a more general ManagedType >Fix: MapAttribute constructor should be relaxed to except a ManagedType The existing comment support shis change // Set the managedType (X or owning Type) - Note: EmbeddableTypes are only supported as Map keys here >Code under question Thread [main] (Suspended (breakpoint at line 1152 in ManagedTypeImpl)) EmbeddableTypeImpl<X>(ManagedTypeImpl<X>).initialize() line: 1152 MetamodelImpl.initialize() line: 399 MetamodelImpl.<init>(DatabaseSession) line: 101 MetamodelImpl.<init>(EntityManagerSetupImpl) line: 120 EntityManagerSetupImpl.getMetamodel() line: 1939 EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 385 if (collectionContainerPolicy.isMapPolicy() || collectionContainerPolicy.isDirectMapPolicy()) { // Handle the 3 Map type mappings (policy.isMappedKeyMapPolicy()) is handled by isMapPolicy()) member = new MapAttributeImpl((IdentifiableTypeImpl)this, colMapping, true); - calls protected MapAttributeImpl(IdentifiableTypeImpl<X> managedType, CollectionMapping mapping, boolean validationEnabled) { >Model: @Embeddable @Access(AccessType.FIELD) public class ContactInfo { @Embedded private Address residence; @ManyToOne @JoinColumn(name = "PRI_NUM") private Phone primaryPhone; @ManyToMany @MapKey(name = "type") @JoinTable(name = "EMP_PHONES") > private Map<String, Phone> phones; } @Entity public class Employee { @Id private int id; @Embedded @AttributeOverride(name = "address.zip", column = @Column(name = "ZIP")) @AssociationOverrides( { @AssociationOverride(name = "primaryPhone", joinColumns = @JoinColumn(name = "PRI_NUM")), @AssociationOverride(name = "phones", joinTable = @JoinTable(name = "EMP_PHONES")) }) private ContactInfo contactInfo;
Created attachment 154287 [details] MapAttribute should not narrow managedType to identifiableType
>Logs without fix: during an em.persist() [EL Severe]: 2009-12-11 00:43:20.345--ServerSession(747212)--Thread(Thread[main,5,main])--java.lang.ClassCastException: org.eclipse.persistence.internal.jpa.metamodel.EmbeddableTypeImpl cannot be cast to org.eclipse.persistence.internal.jpa.metamodel.IdentifiableTypeImpl at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.initialize(ManagedTypeImpl.java:1152) at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.initialize(MetamodelImpl.java:399) at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:101) at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:120) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.getMetamodel(EntityManagerSetupImpl.java:1939) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:385)
>Verified on Glassfish V3 B73 by hacking the org.eclipse.persistence.jpa.jar bundle 1 of 6 >Before [exec] Caused by: javax.persistence.PersistenceException: java.lang.ClassCastException: org.eclipse.persistence.internal.jpa.metamodel.EmbeddableTypeImpl cannot be cast to org.eclipse.persistence.internal.jpa.metamodel.IdentifiableTypeImpl [exec] at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:390) [exec] at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151) [exec] at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207) [exec] at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202) [exec] at com.sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.java:197) [exec] at com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:424) >After [exec] [#|2009-12-14T03:12:16.060-0500|INFO|glassfishv3.0|org.eclipse.persistence.session.file:/C:/_JPA/glassfish/ glassfish/domains/domain1/applications/embeddedObjects/embeddedObjects_jar/_EmployeeService|_ThreadID=26;_ThreadName=http-thread-p ool-8080-(1);|file:/C:/_JPA/glassfish/glassfish/domains/domain1/applications/embeddedObjects/embeddedObjects_jar/_Emplo yeeService login successful|#]
The use case for this 297555 issue is an Embedded Id that itself contains a Map relationship. Fix for trunk and 2.0.1 is to remove the cast to the more narrow IdentifiableType for EmbeddableTypes >Future: As we discussed, don't let a metamodel issue hold up deployment - either now or even after a future change to the API. Any CCE or similar exception in the no longer lazy em.getMetamodel() breaks deployment - do a fail fast, send notification about a broken metamodel (due to any current or future broken function implementation or incorrect schema) and continue on with the deployment.
>Use case is a more general Map attribute on an Embedded Test model is a unidirectional @ManyToMany in Observation back to Person (as observer) >See SVN rev# 6064 (2.0.1) and 6065 (2.1 trunk) http://fisheye2.atlassian.com/changelog/eclipselink/?cs=6064 http://fisheye2.atlassian.com/changelog/eclipselink/?cs=6065 >See modified DI 92 http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_92:_20091008:_Move_metamodel_instance_field_from_EntityManagerFactory_to_EntityManagerSetupImpl
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink