This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 297555 - JPA2: Metamodel: CCE narrowing MapAttribute type on ManagedType(EmbeddableType) to IdentifiableType - for Map on an Embedded
Summary: JPA2: Metamodel: CCE narrowing MapAttribute type on ManagedType(EmbeddableTyp...
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Michael OBrien CLA
QA Contact:
URL: http://wiki.eclipse.org/EclipseLink/D...
Whiteboard:
Keywords:
Depends on: 266912
Blocks:
  Show dependency tree
 
Reported: 2009-12-11 01:16 EST by Michael OBrien CLA
Modified: 2022-06-09 10:10 EDT (History)
1 user (show)

See Also:


Attachments
MapAttribute should not narrow managedType to identifiableType (2.51 KB, patch)
2009-12-11 01:19 EST, Michael OBrien CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael OBrien CLA 2009-12-11 01:16:49 EST
>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;
Comment 1 Michael OBrien CLA 2009-12-11 01:19:48 EST
Created attachment 154287 [details]
MapAttribute should not narrow managedType to identifiableType
Comment 2 Michael OBrien CLA 2009-12-11 01:22:49 EST
>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)
Comment 3 Michael OBrien CLA 2009-12-14 03:12:16 EST
>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|#]
Comment 4 Michael OBrien CLA 2009-12-14 10:02:23 EST
    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.
Comment 5 Michael OBrien CLA 2009-12-14 16:07:32 EST
>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
Comment 6 Eclipse Webmaster CLA 2022-06-09 10:10:23 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink