JPA entity class autoenrollment under "technology" javase environment

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.