This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 289487 - JPA: DatabaseField type and typeName different for @BasicMap with @ObjectTypeConverter
Summary: JPA: DatabaseField type and typeName different for @BasicMap with @ObjectType...
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows Vista
: P4 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL: http://wiki.eclipse.org/EclipseLink/D...
Whiteboard:
Keywords:
Depends on: 314906
Blocks:
  Show dependency tree
 
Reported: 2009-09-15 11:31 EDT by Michael OBrien CLA
Modified: 2022-06-09 10:03 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael OBrien CLA 2009-09-15 11:31:15 EDT
>This issue arose when testing BasicMap support in the Metamodel API for MapAttributeImpl when we found out that using the field.type (Class) was not working when an @ObjectTypeConverter has modified the type class to reflect the actual type on the database.  
At this point the typeName correctly reflects the object type (Long) and the type reflects the database type (String).

>Model
org.eclipse.persistence.testing.models.jpa.advanced.Buyer

    @BasicMap(
        fetch=EAGER,
        keyColumn=@Column(name="CARD"),
        keyConverter=@Convert("CreditCard"),
        valueColumn=@Column(name="NUMB"),
        valueConverter=@Convert("Long2String")
    )
    @ObjectTypeConverter(
        name="CreditCard",
        conversionValues={
            @ConversionValue(dataValue="VI", objectValue=VISA),
            @ConversionValue(dataValue="AM", objectValue=AMEX),
            @ConversionValue(dataValue="MC", objectValue=MASTERCARD),
            @ConversionValue(dataValue="DI", objectValue=DINERS)
        }
    )
    @PrivateOwned
    // Default the collection table BUYER_CREDITCARDS
    public Map<String, Long> getCreditCards() {
        return creditCards;


>Debugging
>typeName is correct, type is not (but is the correct database type)
mapping	DirectMapMapping  (id=143)	
	attributeAccessor	MethodAttributeAccessor  (id=263)	
	attributeName	"creditCards" (id=266)	
	cascadeMerge	false	
	cascadePersist	false	
	cascadeRefresh	false	
	cascadeRemove	false	
	changeOrderTargetQuery	null	
	changeSetDeleteQuery	DataModifyQuery  (id=267)	
	containerPolicy	DirectMapContainerPolicy  (id=152)	
		cloneMethod	null	
		constructor	Constructor<T>  (id=281)	
		containerClass	Class<T> (java.util.Hashtable) (id=284)	
		containerClassName	"java.util.Hashtable" (id=286)	
		elementDescriptor	RelationalDescriptor  (id=122)	
		valueField	DatabaseField  (id=274)	
			columnDefinition	"" (id=318)	
			index	0	
			isInsertable	true	
			isNullable	true	
			isUnique	false	
			isUpdatable	true	
			length	255	
			name	"NUMB" (id=323)	
			precision	0	
			qualifiedName	"Buyer_CREDITCARDS.NUMB" (id=322)	
			scale	0	
			sqlType	-2147483648	
			table	DatabaseTable  (id=320)	
			type	Class<T> (java.lang.String) (id=175)	
			typeName	"java.lang.Long" (id=324)	
			useDelimiters	false	
	weight	Integer  (id=338)	

>this one is ok
containerPolicy	DirectMapContainerPolicy  (id=149)	
	cloneMethod	null	
	constructor	Constructor<T>  (id=174)	
	containerClass	Class<T> (org.eclipse.persistence.indirection.IndirectMap) (id=178)	
	containerClassName	"org.eclipse.persistence.indirection.IndirectMap" (id=179)	
	elementDescriptor	RelationalDescriptor  (id=107)	
	keyConverter	null	
	keyConverterClassName	null	
	keyField	DatabaseField  (id=180)	
	valueConverter	null	
	valueField	DatabaseField  (id=157)	
		columnDefinition	"" (id=183)	
		index	0	
		isInsertable	true	
		isNullable	true	
		isUnique	false	
		isUpdatable	true	
		length	255	
		name	"AWARD_CODE" (id=184)	
		precision	0	
		qualifiedName	"NOVICE_CONSUMER_AWARDS.AWARD_CODE" (id=182)	
		scale	0	
		sqlType	-2147483648	
		table	DatabaseTable  (id=185)	
		type	Class<T> (java.lang.Integer) (id=110)	
		typeName	"java.lang.Integer" (id=187)	
		useDelimiters	false	

>Workaround: see design issue #83 and #81
- either use typeName and create a Class using ConversionManager, or add the attributeClassification fields to DirectCollectionMapping.

http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_83:_20090914:_MapAttributeImpl.elementType_incorrectly_set_when_.40ObjectTypeConverter_is_present
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_81:_20090914:_Implement_.40BasicMap_DirectMapContainerPolicy_support_in_MapAttributeImpl

>Note: the workaround for Metamodel processing is sufficient - this bug should be tracked and possibly fixed or enhanced - post release.

>see bug# 266912
Comment 1 Michael OBrien CLA 2009-09-15 13:24:23 EDT
>code reference - typeName is stated as being a shadow variable - however typeName is set along with type only if typeName==null (typeName is a single-write field in effect)

DatabaseField.java
    /**
     * Respective Java type desired for the field's value, used to optimize performance and for binding.
     * PERF: Allow direct variable access from getObject.
     */
    public transient Class type;
    public String typeName; // shadow variable - string name of above Class type variable

    /**
     * Set the Java class type that corresponds to the field.
     * The JDBC type is determined from the class type,
     * this is used to optimize performance, and for binding.
     */
    public void setType(Class type) {
        this.type = type;
        if (this.type != null && typeName == null) {
            typeName = this.type.getName();
        }
    }
Comment 2 Eclipse Webmaster CLA 2022-06-09 10:03:24 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink