Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Virtual Metlhods | questions

Hi Gaurav,

In general, you should not have to manage the valueholders for your xToMany relationships. Instead of useBasicIndirection(), call useTransparentIndirection() for your xToManys and the LAZYness will be managed under the covers.

-Tom

On 19/07/2012 9:06 AM, Gaurav Malhotra wrote:

Hi Tom/Chris,
  I made it work. Please give it look and give me some feedback. I had
downloaded the  TLG JPA Grid Cache example and added following relationships
(using TLG to make sure every thing works in grid also)
  1) 1-1 with TLG_GC_PHONE
  2) 1-* with TLG_GC_PHONE
   (above relationship with TLG_GC_PHONE is purely imaginary to test
programmatic creation of mappings a map)
  3) Direct field mapping extChar0

My session customizer looks like

public class GridCacheSessionCustomizer implements SessionCustomizer {
	
	public static Map<String, Boolean>  foreignReferenceMappingInformer = new
ConcurrentHashMap<String, Boolean>();
	

	public void customize(Session session) throws Exception {
		ClassDescriptor classDescriptor = session.getDescriptor(Employee.class);
		
		diirectFieldMapping(classDescriptor);
		
		oneToOneMapping(classDescriptor);
		
		oneToManyMapping(classDescriptor);
		
	}
	
	public static boolean isForeignReferenceMapping(Class<?>  klass, String
property) {
		Boolean retValue =
foreignReferenceMappingInformer.get(String.format("%s#%s",
klass.getCanonicalName(),property));
		return retValue != null ? retValue : false;
	}
	
	/**
	 * Dynamically/programatically creating {@link OneToManyMapping}
	 */
	private void oneToManyMapping(ClassDescriptor classDescriptor) {
		OneToManyMapping oneToManyMapping = new OneToManyMapping();
		oneToManyMapping.setDescriptor(classDescriptor);
		oneToManyMapping.setCascadeAll(true);
		oneToManyMapping.useBasicIndirection();
		
		VirtualAttributeAccessor virtualAttributeAccessor2 = new
VirtualAttributeAccessor();
		virtualAttributeAccessor2.setAttributeName("phoneNumbers");
		virtualAttributeAccessor2.setGetMethodName("getListValueHolder");
		virtualAttributeAccessor2.setSetMethodName("setListValueHolder");
		virtualAttributeAccessor2.setValueType(ValueHolderInterface.class);

	
virtualAttributeAccessor2.initializeAttributes(classDescriptor.getJavaClass());
		
		oneToManyMapping.setAttributeAccessor(virtualAttributeAccessor2);
		oneToManyMapping.setAttributeName("phoneNumbers");
		oneToManyMapping.setReferenceClass(PhoneNumber.class);
		Vector<String>  sourceFieldNames = new Vector<String>();
		sourceFieldNames.add("PHONE_NUMBER_ID");
		oneToManyMapping.setSourceKeyFieldNames(sourceFieldNames);
		
		
		Vector<String>  targetFieldNames = new Vector<String>();
		targetFieldNames.add("ID");
		oneToManyMapping.setTargetForeignKeyFieldNames(targetFieldNames);
		
		classDescriptor.getMappings().add(oneToManyMapping);
	}

	/**
	 * Dynamically/programatically create {@link OneToOneMapping}
	 */
	private void oneToOneMapping(ClassDescriptor classDescriptor) {
		OneToOneMapping oneToOneMapping = new OneToOneMapping();
		oneToOneMapping.setDescriptor(classDescriptor);
		oneToOneMapping.setCascadeAll(true);
		oneToOneMapping.useBasicIndirection();
		
		VirtualAttributeAccessor virtualAttributeAccessor2 = new
VirtualAttributeAccessor();
		virtualAttributeAccessor2.setAttributeName("phoneNumber");
		virtualAttributeAccessor2.setGetMethodName("getValueHolder");
		virtualAttributeAccessor2.setSetMethodName("setValueHolder");
		virtualAttributeAccessor2.setValueType(ValueHolderInterface.class);
	
virtualAttributeAccessor2.initializeAttributes(classDescriptor.getJavaClass());
		
		foreignReferenceMappingInformer.put(String.format("%s#%s",
classDescriptor.getJavaClassName(),"phoneNumber"), Boolean.TRUE);
		
		oneToOneMapping.setAttributeAccessor(virtualAttributeAccessor2);
		oneToOneMapping.setAttributeName("phoneNumber");
		oneToOneMapping.setReferenceClass(PhoneNumber.class);
		oneToOneMapping.addForeignKeyFieldName("TLG_GC_EMPLOYEE.PHONE_NUMBER_ID",
"TLG_GC_PHONE.ID");
		
		
		classDescriptor.getMappings().add(oneToOneMapping);
	}

	/**
	 * Dynamically/programatically create {@link DirectToFieldMapping}
	 */
	private void diirectFieldMapping(ClassDescriptor classDescriptor) {
		DirectToFieldMapping directToFieldMapping1 = new DirectToFieldMapping();
		directToFieldMapping1.setDescriptor(classDescriptor);
		
		VirtualAttributeAccessor virtualAttributeAccessor1 = new
VirtualAttributeAccessor();
		virtualAttributeAccessor1.setAttributeName("extChar0");
		virtualAttributeAccessor1.setGetMethodName("get");
		virtualAttributeAccessor1.setSetMethodName("set");
	
virtualAttributeAccessor1.initializeAttributes(classDescriptor.getJavaClass());
		
		directToFieldMapping1.setAttributeAccessor(virtualAttributeAccessor1);
		directToFieldMapping1.setAttributeClassification(String.class);
		directToFieldMapping1.setAttributeName("extChar0");
		
		DatabaseField databaseField1 = new DatabaseField("char_0");
		databaseField1.setNullable(false);
		databaseField1.setType(String.class);
		
		directToFieldMapping1.setField(databaseField1);
		
		classDescriptor.getMappings().add(directToFieldMapping1);
	}

}

My Employee class looks like

public class Employee implements Serializable {
	private static final long serialVersionUID = 299555566217698138L;

	@Id
	@GeneratedValue
	private int id;
	private String firstName;
	private String lastName;
//	@OneToMany(mappedBy="owner", cascade = ALL)
//	private List<PhoneNumber>  phoneNumbers = new ArrayList<PhoneNumber>();
	@OneToOne(cascade = ALL, fetch=FetchType.LAZY)
	private Address address;
	@Version
	private long version;
	
	@Transient
	private Map<String, Object>  extensions = new HashMap<String, Object>();
	
	
	public Object get(String key) {
		
		return ValueHolderInterface.class.isInstance(extensions.get(key)) ?
ValueHolderInterface.class.cast(extensions.get(key)).getValue() :
extensions.get(key);
	}
	
	public void set(String key,Object value) {
		if (GridCacheSessionCustomizer.isForeignReferenceMapping(getClass(), key))
{
			setValueHolder(key, getValueHolder(key));
		} else {
			extensions.put(key, value);
		}
	}
	
	
	public ValueHolderInterface getValueHolder(String key) {
		if (extensions.containsKey(key)) {
			Object value = extensions.get(key);
			if (ValueHolderInterface.class.isInstance(value)) {
				return ValueHolderInterface.class.cast(extensions.get(key));
			}
		}
		extensions.put(key, new ValueHolder());
		return ValueHolderInterface.class.cast(extensions.get(key));
	}	
	
	public void setValueHolder(String key,ValueHolderInterface value) {
		extensions.put(key, value);
	}	
	
	public ValueHolderInterface getListValueHolder(String key) {
		if (extensions.containsKey(key)) {
			Object value = extensions.get(key);
			if (ValueHolderInterface.class.isInstance(value)) {
				return ValueHolderInterface.class.cast(extensions.get(key));
			}
		}
		extensions.put(key, new ValueHolder(new ArrayList()));
		return ValueHolderInterface.class.cast(extensions.get(key));
	}	
	
	public void setListValueHolder(String key,ValueHolderInterface value) {
		extensions.put(key, value);
	}	
	

	public Employee() {
	}

	public int getId() {
		return id;
	}

	public void setId(int empId) {
		this.id = empId;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String fName) {
		this.firstName = fName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lName) {
		this.lastName = lName;
	}

	public long getVersion() {
		return version;
	}

	@SuppressWarnings("unchecked")
	public List<PhoneNumber>  getPhoneNumbers() {
		Object phoneNumbers = get("phoneNumbers");
		
		if (phoneNumbers == null) {
			return List.class.cast(getListValueHolder("phoneNumbers").getValue());
		}
		
		return List.class.cast(phoneNumbers);
		
	}

	public void setPhoneNumbers(List<PhoneNumber>  phoneNumberList) {
		set("phoneNumbers", phoneNumberList);
	}

	public PhoneNumber addPhoneNumber(PhoneNumber phoneNumber) {
		getPhoneNumbers().add(phoneNumber);
		phoneNumber.setOwner(this);
		return phoneNumber;
	}

	public PhoneNumber addPhoneNumber(String type, String areaCode, String
number) {
		PhoneNumber phoneNumber = new PhoneNumber(type, areaCode, number);
		return addPhoneNumber(phoneNumber);
	}

	public PhoneNumber removePhoneNumber(PhoneNumber phoneNumber) {
		getPhoneNumbers().remove(phoneNumber);
		phoneNumber.setOwner(null);
		return phoneNumber;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public Address getAddress() {
		return address;
	}

	public String toString() {
		return "Employee(" + getId() + ": " + getLastName() + ", " +
getFirstName() + "Extension map (will contain value holder for 1-1&  1-*" +
extensions + ")";
	}

}





Back to the top