JPA Hibernate Dynamic entity mapping & persistence at runtime

后端 未结 2 1098
感动是毒
感动是毒 2021-01-19 21:55

Basically we have a spring boot application that requires that the user can define his/her own set of fields and that these fields should be persisted in their own class/tab

相关标签:
2条回答
  • 2021-01-19 22:41

    Hibernate maps entities to tables, and the metadata is built during bootstrap. So, you can't modify it on the fly while the application is running.

    However, as long as you keep on adding new tables without modifying the existing structure, you can address this issue at the architecture level:

    1. You make the class changes you need.
    2. You build the project artifacts.
    3. You deploy the new project artifacts to a new server.
    4. You switch traffic from the old server instance to the new one from the load balancer without any downtime.

    Or, just use a NoSQL database like MongoDB with Hibernate OGM since your requirements do not fit very well into a relational database anyway.

    But, if you already use a RDBMS, then it's simpler to just use JSON instead of switching to a NoSQL database just for that reason.

    0 讨论(0)
  • 2021-01-19 22:53

    Firstly, the problem is how to add entity class in hot-deploy. We could do it by some tools of swapping (spring-boot-devtools, or maven copy resource). Secondly, to architect the different models of an entity, could use JPA Inheritance(https://en.wikibooks.org/wiki/Java_Persistence/Inheritance) or JPA row mapper.

    But, I see it is more easily to persistence JSON object as text in the database, and left the consumer(front or another service) of the service to parse it.

    Another way to do it, is to try load class in runtime by its class path. I will try to persistence Json object as text and its type in ddbb. Then in application.properties create the mapping of its type and classpath (the class java of the data), then do something like:

    static{
         Map<String, String> typeClassPathMap = ......// from properties
         File file = new File("c:\\class-path\\");
        // Convert File to a URL
        URL url = file.toURL();          
        // file:/c:/myclasses/
        URL[] urls = new URL[]{url};
        ClassLoader cl = new URLClassLoader(urls);
    }
    
     Class<?> loadClass(String type){
    
        Class clazz = urlClassLoader.loadClass(typeClassPathMap.get(type));
     }
    

    It will read class in runtime and is configurable by properties. After that, for each type of data, we define su type and class path in the property file. When data come from ddbb, we use its type to get the java class, and parse it to object. When we need to create new type of data, we left the class in class-path, and configure it in properties.

    0 讨论(0)
提交回复
热议问题