Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Tricky custom ClassLoader problem
Tricky custom ClassLoader problem [message #1393380] Thu, 03 July 2014 18:07
Peter Sauer is currently offline Peter SauerFriend
Messages: 1
Registered: July 2014
Junior Member
Hi!

We are developing a web based graphical database: Vaadin (GUI) with a generic layer for DB access supporting Hibernate & JPA (EclipseLink, HibernateJPA and ObjectDB). Works fine. But now we are trying to find a general solution for control the @Table/@Index attributes.

Static annotaions in the source code like
@Table(indexes = {  @Index(columnList = "ci"),@Index(columnList = "uiElement"),@Index(columnList = "histId")})

work fine.

But now we try to use dynamic modfied annotations. See the code at the end of the posting. With this approach you can collect the @Index attributes over all subclasses and create a new @Table annotation, or create DB specific @Index. This tricky code works fine for Hibernate. But for EclipseLink the modified annotation/class is ignored by EclipseLink. The custom PersistenceUnitProperties.CLASSLOADER works, but this loader is called after table creation. The table creation process uses the unmodified annotations/class invoking an other class loader.

Any idea to solve this tricky problem.
with best regards.
Peter




public class ChangeAnnotation {

	public static void test(Class<?> clazz) {
		Annotation a = clazz.getAnnotation(Table.class);
		Table t = (Table) a;
		for (Index i : t.indexes()) {
			System.out.println(i.columnList());
		}
	}

	public static Index createIndex(final String columnList) {
		return (Index) Proxy.newProxyInstance(Index.class.getClassLoader(),
				new Class[] { Index.class }, new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) {
						if (method.getName().equals("columnList")) {
							return columnList;
						} else {
							return "";
						}
					}
				});
	}

	private static void collectIndexes(final Class<?> clazz,
			ArrayList<Index> list) {
		Annotation a = clazz.getAnnotation(Table.class);
		Table t = (Table) a;
		for (Index i : t.indexes()) {
			list.add(i);
		}
		Class<?> s = clazz.getSuperclass();
		Annotation mapped = s.getAnnotation(MappedSuperclass.class);
		if (mapped  != null) {
			collectIndexes(s, list);
		}
	}

	public static void rebuildIndexAnnotations(final Class<?> clazz)
			throws Exception {
		Annotation a = Class.forName(clazz.getName()).getAnnotation(Table.class);
		if(a == null) {
			return;
		}
		ArrayList<Index> list = new ArrayList<Index>();
		collectIndexes(clazz, list);
		Table t = (Table) a;
		if (list.size() > 0 && (t.indexes().length != list.size())) {
			Object invocationHandler = Proxy.getInvocationHandler(a);
			Field field = invocationHandler.getClass().getDeclaredField(
					"memberValues");
			field.setAccessible(true);
			LinkedHashMap<String, Object[]> map = (LinkedHashMap<String, Object[]>) field
					.get(invocationHandler);
			map.put("indexes", list.toArray(new Index[list.size()]));
			field.set(invocationHandler, map);
		}

	}

	public static void main(String args[]) throws Exception {	
		rebuildIndexAnnotations(CIimage.class);
		test(CIimage.class);
	}
	
}
Previous Topic:Best type for JPA version field for Optimistic locking
Next Topic:JPQL passing binary enum instead of enum's ordinal as SQL param value for key in Map<enum, String
Goto Forum:
  


Current Time: Thu Apr 02 00:27:35 GMT 2015

Powered by FUDForum. Page generated in 0.14739 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software