In environments where there is no container support, JPA entity classes (entities) are typically registered individually in Persistence.xml, similar to the following:
1 <?XML version= "1.0" encoding= "UTF-8"?>2 <Persistenceversion= "2.1"xmlns= "Http://xmlns.jcp.org/xml/ns/persistence"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"xsi:schemalocation= "Http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">3 <Persistence-unitname= "Security-common">4 <class>Org.gems.han.security.common.MenuVO</class>5 <class>Org.gems.han.security.common.MenuItemVO</class>6 <class>Org.gems.han.security.common.ModuleVO</class>7 <class>Org.gems.han.security.common.RoleVO</class>8 <class>Org.gems.han.security.common.UserVO</class>9 <class>Org.gems.han.security.common.UserRoleVO</class>Ten </Persistence-unit> One </Persistence>
I do not know if everyone is as I feel very troublesome, but also very confused, clearly each entity class are marked @entity, why do you want to register again? Is there a way to use @entity tags to exempt registered entity classes from trouble? After research, find the following solutions, share to everyone.
Let's start by explaining that the JPA implementation I'm using is eclipselink, and my scenario is only validated under that implementation.
We know that Entitymanagerfactory was created by Persistenceprovider, and we started with it to try to solve the problem. This class has different implementation classes in different JPA implementations, Eclipselink is Org.eclipse.persistence.jpa.PersistenceProvider, we first inherit this class, covering the method Createentitymanagerfactoryimpl, as follows:
1 @Override2 protectedEntitymanagerfactoryimpl Createentitymanagerfactoryimpl (persistenceunitinfo puinfo, Map properties,3 Booleanrequiresconnection) {4List<string> classnamelist =puinfo.getmanagedclassnames ();5List<string> entityclassnamelist =getmanagedclassnames ();6 Classnamelist.addall (entityclassnamelist);7 return Super. Createentitymanagerfactoryimpl (Puinfo, properties, requiresconnection);8}
principle: line 4th, if there is no entity class registered in Persistence.xml, then Classnamelist will be an empty list (note is empty list, not null), line 5th, The entity class is obtained by means of the method Getmanagedclassnames, the 6th line, the entity class is added to the list, and the 7th line, called the parent class method, implements the creation of the factory class. The following key is the implementation of the Getmanagedclassnames method. Here I use Google's Open source project guava to scan the Java class, and then filter the entity class with the @entity tag, with the following code:
1 PublicList<string>Getmanagedclassnames () {2List<string> managedclassnamelist =NewArraylist<>();3ClassLoader loader =Thread.CurrentThread (). Getcontextclassloader ();4Immutableset<classinfo> cs =NULL;5 Try {6CS =classpath.from (loader). gettoplevelclasses ();7}Catch(IOException e) {8 e.printstacktrace ();9 }TenManagedclassnamelist =NewArraylist<>(); One if(cs! =NULL&& cs.isempty () = =false) { A for(ClassInfo ci:cs) { -class<?> C =NULL; - Try { thec =Loader.loadclass (Ci.getname ()); -}Catch(Throwable ex) { - } - if(c! =NULL) { +Entity entity = C.getannotation (entity.class); - if(Entity! =NULL) { + Managedclassnamelist.add (C.getname ()); A } at } - } - } - returnmanagedclassnamelist; -}
where the ClassLoader (loader) is used depending on the situation, but if a special classloader is used, The Org.eclipse.persistence.jpa.PersistenceProvider getClassLoader method needs to be overwritten to ensure that the entity classes are loaded properly at runtime.
In addition, it was found in the experiment that Persisitenceprovider was loaded via SPI, not according to the settings in Profile Persistence.xml. Therefore, you need to add the Services/javax.persistence.spi.persistenceprovider file under Meta-inf to write our own persistenceprovider in the file. I have some doubts about this, and I ask you to verify it in practice.
JPA entity class autoenrollment under "technology" javase environment