Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa Eclipselink实体映射缓存_Jpa_Orm_Mapping_Eclipselink_Entitymanager - Fatal编程技术网

Jpa Eclipselink实体映射缓存

Jpa Eclipselink实体映射缓存,jpa,orm,mapping,eclipselink,entitymanager,Jpa,Orm,Mapping,Eclipselink,Entitymanager,我正在为我的项目使用EclipseLink。 我扩展了XMLMetadataSource(以提供自定义类加载器),因为我持久化的实体是运行时创建的。它工作正常 当我执行以下操作时,我得到了“未知实体类型” 创建实体 创建映射 创建实体管理器工厂,提供自定义类加载器 创建实体管理器并持久化。-它工作正常 现在删除实体,并从类加载器中删除 创建相同的实体 再次创建映射(当然看起来是一样的) 尝试使用新属性(新类加载器、映射文件)刷新实体管理器工厂 尝试坚持-抱怨“未知类型” 如果EL缓存XML映

我正在为我的项目使用EclipseLink。 我扩展了XMLMetadataSource(以提供自定义类加载器),因为我持久化的实体是运行时创建的。它工作正常

当我执行以下操作时,我得到了“未知实体类型”

  • 创建实体

  • 创建映射

  • 创建实体管理器工厂,提供自定义类加载器

  • 创建实体管理器并持久化。-它工作正常

  • 现在删除实体,并从类加载器中删除

  • 创建相同的实体

  • 再次创建映射(当然看起来是一样的)

  • 尝试使用新属性(新类加载器、映射文件)刷新实体管理器工厂

  • 尝试坚持-抱怨“未知类型”

如果EL缓存XML映射,你知道吗。 我试图重新创建工厂,但同样的错误

我试过MySQL和德比。使用“删除并创建表”和“创建或扩展表”


相同的结果。

是的,持久性单元加载只执行一次。如果使用XMLMetadataSource更改映射,则必须告诉工厂使用EMF上的refreshMetadata()刷新其映射,如下所述:


之后,获得的下一个EntityManager将使用新的映射,而现有的EMs仍将使用旧的映射。

我在eclipse链接中提交了一个bug


这不是EL中的一个漏洞。但问题在于EL“没有构建或重新创建“类-->类描述符”映射(一个包含每个实体的类对象和实体描述的内部映射)。我偶然发现了这一点。对于那些感兴趣的人,这里有一个示例代码可能会有所帮助

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);


}
公共类Test1{
公共测试1(字符串pu、地图道具){
pu_name=pu;
properties=newhashmap();
属性。putAll(道具);
loader=新的MyClassLoader();
}
公共无效初始化(){
mms=新的WAMetadataSource();
properties.put(PersistenceUnitProperties.METADATA\u源,mms);
properties.put(PersistenceUnitProperties.CLASSLOADER,loader);
如果(emf==null | |!emf.isOpen()){
已同步(Test1.class){
如果(emf==null | |!emf.isOpen()){
emf=Persistence.createEntityManagerFactory(pu_名称、属性);
} 
}            
}否则{
getEntityManagerFactory(emf).refreshMetadata(属性);
}
System.out.println(“=======>refreshed.emf.hascode:“+emf.hashCode()+”,loader.h:“+loader.hashCode()”);
}公共实体管理器getEntityManager(地图道具){
if(em==null){
em=emf.createEntityManager(道具);
}
返回em;
}公共void持久化(对象obj){
试一试{
getEntityManager(属性);
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();
}最后{
}    
}公共对象getRuntimeEntityObject(int ii){
objectobj=null;
Class clazz=loader.loadClass(“com.xxx.sample.entity.runtime.User”);
如果(ii==1){
obj=clazz.getConstructor(String.class).newInstance(“Jai-Ramjiki-1”);
}否则{
obj=clazz.getConstructor(String.class).newInstance(“Jai-Ramjiki-2”);
}
obj=分层铸造(obj);
返回obj;
}公共静态void main(字符串[]args){
Map props=newhashmap();
put(PersistenceUnitProperties.JDBC_驱动程序,“com.mysql.JDBC.DRIVER”);
put(PersistenceUnitProperties.JDBC_URL,“JDBC:mysql://localhost:3306/test" );
put(PersistenceUnitProperties.JDBC_用户,“root”);
put(PersistenceUnitProperties.JDBC_密码,“root”);
put(PersistenceUnitProperties.DDL_生成,“创建或扩展表”);
test1t1=newtest1(“mysql”,props);
Object obj1=t1.getRuntimeEntityObject(1);
System.out.println(“*****>obj1=“+obj1+”,类加载器哈希代码:“+obj1.getClass().getClassLoader().hashcode());
t1.初始化();
t1.持久化(obj1);
System.out.println(“类1:+obj1.getClass().hashCode()+”,obj1:+obj1);
t1.close();
//现在删除前面的类装入器并重新运行相同的类装入器。
test1t2=newtest1(“mysql”,props);
Object obj2=t2.getRuntimeEntityObject(2);
System.out.println(“*****>obj2=“+obj2+”,类加载器hashcode:“+obj2.getClass().getClassLoader().hashcode()”);
t2.初始化();
t2.持续存在(obj2);
t2.关闭();
objectobj3=t1.getRuntimeEntityObject(1);
System.out.println(“**>obj3=“+obj3+”,类加载器哈希代码:“+obj3.getClass().getClassLoader().hashcode());
t1.持久性(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);
}
@覆盖
公共XMLEntityMappings getEntityMappings(映射属性、类加载器类加载器、会话日志){
put(PersistenceUnitProperties.METADATA_SOURCE_XML_文件,“eclipselink orm user.XML”);
properties.put(PersistenceUnitProperties.VALIDATOR_FACTORY,null);
返回super.getEntityMappings(属性、类加载器、日志);
}
并在CustomClassloader中使用javassist创建一个运行时类,该类扩展了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);    
}
public void createRuntimeClass(字符串类名称)引发异常{
CtClass bclass=pool.makeClass(类名);
bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
映射字段=新的HashMap();
添加字段(字段);
int noOfFields=fields.size();
CtClass[]fclasses=新CtClass[noOfFields];
int ii=0;
for(输入字段:fields.entrySet()){
字符串fieldName=field.getKey();
字符串fieldType=field.getValue();
//
public Class<?> loadClass(String name) throws ClassNotFoundException {return clazz = loadedClasses.get(name);}

public InputStream getResourceAsStream(String name) {return loadClassBytes.get(className);}