Его не ошибка в говорят в EL. Но проблема заключается в том, что EL «не создает или не воссоздает» class -> class_descriptor 'map (внутренняя карта, которая содержит объект класса каждого описания сущности и сущностей) .Я обнаружил это случайно. Для тех, кого это интересует, вот пример кода это может помочь.
public class Test1 {
public Test1(String pu, Map<String, Object> props) {
pu_name = pu;
properties = new HashMap<String, Object>();
properties.putAll(props);
loader = new MyClassLoader();
}
public void initialization() {
mms = new WAMetadataSource();
properties.put(PersistenceUnitProperties.METADATA_SOURCE, mms);
properties.put(PersistenceUnitProperties.CLASSLOADER,loader);
if(emf == null || !emf.isOpen()) {
synchronized(Test1.class) {
if (emf == null || !emf.isOpen()) {
emf = Persistence.createEntityManagerFactory(pu_name, properties);
}
}
} else {
JpaHelper.getEntityManagerFactory(emf).refreshMetadata(properties);
}
System.out.println("======> refreshed. emf.hascode : " + emf.hashCode() + ", loader.h : " + loader.hashCode());
} public EntityManager getEntityManager(Map<String, Object> props) {
if (em == null) {
em = emf.createEntityManager(props);
}
return em;
} public void persist(Object obj) {
try {
getEntityManager(properties);
System.out.println("===> em.hascode =" + em.hashCode() +", " + JpaHelper.getEntityManager(em).getProperties().get(PersistenceUnitProperties.CLASSLOADER).hashCode());
em.clear();
em.getTransaction().begin();
em.persist(obj);
em.getTransaction().commit();
} finally {
}
}public Object getRuntimeEntityObject(int ii) {
Object obj=null;
Class clazz = loader.loadClass("com.xxx.sample.entity.runtime.User");
if(ii == 1){
obj = clazz.getConstructor(String.class).newInstance("Jai Ramjiki-1");
} else {
obj = clazz.getConstructor(String.class).newInstance("Jai Ramjiki-2");
}
obj = clazz.cast(obj);
return obj;
}public static void main(String[] args) {
Map<String, Object> props = new HashMap<String, Object>();
props.put(PersistenceUnitProperties.JDBC_DRIVER, "com.mysql.jdbc.Driver");
props.put(PersistenceUnitProperties.JDBC_URL, "jdbc:mysql://localhost:3306/test");
props.put(PersistenceUnitProperties.JDBC_USER, "root");
props.put(PersistenceUnitProperties.JDBC_PASSWORD, "root");
props.put(PersistenceUnitProperties.DDL_GENERATION, "create-or-extend-tables");
Test1 t1 = new Test1("mysql", props);
Object obj1 = t1.getRuntimeEntityObject(1);
System.out.println(" ****> obj1 = " + obj1 + ", classloader hashcode : " + obj1.getClass().getClassLoader().hashCode());
t1.initialization();
t1.persist(obj1);
System.out.println("Class 1 : " + obj1.getClass().hashCode() + ", obj1 : " + obj1);
t1.close();
// now drop the previous class loader and rerun same.
Test1 t2 = new Test1("mysql", props);
Object obj2 = t2.getRuntimeEntityObject(2);
System.out.println(" ****> obj2 = " + obj2 + ", classloader hashcode : " + obj2.getClass().getClassLoader().hashCode());
t2.initialization();
t2.persist(obj2);
t2.close();
Object obj3 = t1.getRuntimeEntityObject(1);
System.out.println(" ****> obj3 = " + obj3 + ", classloader hashcode : " + obj3.getClass().getClassLoader().hashCode());
t1.persist(obj3);
}
И продлить XMLMetadatSource
@Override
public XMLEntityMappings getEntityMappings(Map<String, Object> properties, ClassLoader classLoader, SessionLog log) {
properties.put(PersistenceUnitProperties.METADATA_SOURCE_XML_FILE, "eclipselink-orm-user.xml");
properties.put(PersistenceUnitProperties.VALIDATOR_FACTORY, null);
return super.getEntityMappings(properties, classLoader, log);
}
И создать класс выполнения, используя Javassist в вашем CustomClassloader, который проходит ClassLoader
public void createRuntimeClass(String className) throws Exception {
CtClass bclass = pool.makeClass(className);
bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
Map<String, String> fields = new HashMap<String, String>();
addFields(fields);
int noOfFields = fields.size();
CtClass[] fclasses = new CtClass[noOfFields];
int ii=0;
for (Entry<String, String> field : fields.entrySet()) {
String fieldName = field.getKey();
String fieldType = field.getValue();
//.. code to add field
bclass.addField(bfield);
//add getter method.
// add getter and setters
}
CtConstructor userConstructor = CtNewConstructor.make(constructorSource, bclass);
bclass.addConstructor(userConstructor);
byte bytes [] = bclass.toBytecode();
Class cls = bclass.toClass(this, null);
loadedClasses.put(className, cls);
loadClassBytes.put(className, bytes);
}
и Процентовка loadClass и getResourceAsStream методы.
public Class<?> loadClass(String name) throws ClassNotFoundException {return clazz = loadedClasses.get(name);}
public InputStream getResourceAsStream(String name) {return loadClassBytes.get(className);}
надеюсь, что это помогает
EL предоставил способ очистить кэш текущего проекта, а также создание дескрипторов карт. но никто из них не работал. Не уверен, что это предполагаемое поведение или по ошибке они открыли этот API.
Gopi
Спасибо за ваш ответ. На самом деле я делаю обновление – PGK
Спасибо за ваш ответ. На самом деле я делаю обновление, используя следующее. MyXMLMetadataSourceInstance.setClassLoader (myclassloader); props.put (PersistenceUnitProperties.METADATA_SOURCE, MyXMLMetadataSourceInstance); JpaHelper.getEntityManagerFactory (emfactory) .refreshMetadata (реквизит); – PGK
И я заметил, что дескрипторы в 'org.eclipse.persistence.internal.sessions.AbstractSession' /** PERF: дескрипторы кеша из проекта. */ переходные защищенные карты дескрипторы; не может вернуть объект дескриптора класса во второй раз (удаление созданного объекта времени выполнения, воссоздание снова с тем же именем) Я подозреваю, что он кэширован, а при обновлении он не очищается. В любом случае, как очистить весь кеш. Я кратко рассмотрел реализацию интерфейса ProjectCache, но похоже, что создание объекта Project является сложной задачей. –
PGK