2222import jakarta .persistence .metamodel .ManagedType ;
2323import jakarta .persistence .metamodel .Metamodel ;
2424import jakarta .persistence .spi .ClassTransformer ;
25+ import jakarta .persistence .spi .PersistenceUnitInfo ;
2526
27+ import java .net .URL ;
28+ import java .util .Collection ;
2629import java .util .List ;
2730import java .util .Map ;
2831import java .util .Set ;
32+ import java .util .function .Supplier ;
2933
34+ import org .hibernate .cfg .JdbcSettings ;
35+ import org .hibernate .dialect .H2Dialect ;
36+ import org .hibernate .engine .jdbc .connections .internal .UserSuppliedConnectionProviderImpl ;
3037import org .hibernate .jpa .HibernatePersistenceProvider ;
3138import org .hibernate .jpa .boot .internal .EntityManagerFactoryBuilderImpl ;
3239import org .hibernate .jpa .boot .internal .PersistenceUnitInfoDescriptor ;
40+ import org .jspecify .annotations .Nullable ;
41+
42+ import org .springframework .data .repository .config .AotRepositoryContext ;
3343import org .springframework .data .util .Lazy ;
3444import org .springframework .instrument .classloading .SimpleThrowawayClassLoader ;
3545import org .springframework .orm .jpa .persistenceunit .MutablePersistenceUnitInfo ;
46+ import org .springframework .orm .jpa .persistenceunit .PersistenceManagedTypes ;
3647
3748/**
49+ * AOT metamodel implementation that uses Hibernate to build the metamodel.
50+ *
3851 * @author Christoph Strobl
52+ * @author Mark Paluch
3953 * @since 4.0
4054 */
4155class AotMetamodel implements Metamodel {
4256
43- private final String persistenceUnit ;
44- private final Set <Class <?>> managedTypes ;
45- private final Lazy <EntityManagerFactory > entityManagerFactory = Lazy .of (this ::init );
46- private final Lazy <Metamodel > metamodel = Lazy .of (() -> entityManagerFactory .get ().getMetamodel ());
47- private final Lazy <EntityManager > entityManager = Lazy .of (() -> entityManagerFactory .get ().createEntityManager ());
57+ private final Lazy <EntityManagerFactory > entityManagerFactory ;
58+ private final Lazy <EntityManager > entityManager = Lazy .of (() -> getEntityManagerFactory ().createEntityManager ());
4859
49- public AotMetamodel (Set <Class <?>> managedTypes ) {
50- this ("AotMetamodel" , managedTypes );
60+ public AotMetamodel (AotRepositoryContext repositoryContext ) {
61+ this (repositoryContext .getResolvedTypes ().stream ().map (Class ::getName )
62+ .filter (name -> !name .startsWith ("jakarta.persistence" )).toList (), null );
5163 }
5264
53- private AotMetamodel (String persistenceUnit , Set <Class <?>> managedTypes ) {
54- this .persistenceUnit = persistenceUnit ;
55- this .managedTypes = managedTypes ;
65+ public AotMetamodel (PersistenceManagedTypes managedTypes ) {
66+ this (managedTypes .getManagedClassNames (), managedTypes .getPersistenceUnitRootUrl ());
5667 }
5768
58- public static AotMetamodel hibernateModel (Class <?>... types ) {
59- return new AotMetamodel (Set .of (types ));
69+ public AotMetamodel (Collection <String > managedTypes , @ Nullable URL persistenceUnitRootUrl ) {
70+
71+ MutablePersistenceUnitInfo persistenceUnitInfo = new MutablePersistenceUnitInfo () {
72+ @ Override
73+ public ClassLoader getNewTempClassLoader () {
74+ return new SimpleThrowawayClassLoader (this .getClass ().getClassLoader ());
75+ }
76+
77+ @ Override
78+ public void addTransformer (ClassTransformer classTransformer ) {
79+ // just ignore it
80+ }
81+ };
82+ persistenceUnitInfo .setPersistenceUnitName ("AotMetaModel" );
83+
84+ this .entityManagerFactory = init (() -> {
85+
86+ managedTypes .stream ().forEach (persistenceUnitInfo ::addManagedClassName );
87+
88+ persistenceUnitInfo .setPersistenceProviderClassName (HibernatePersistenceProvider .class .getName ());
89+
90+ return new PersistenceUnitInfoDescriptor (persistenceUnitInfo ) {
91+
92+ @ Override
93+ public List <String > getManagedClassNames () {
94+ return persistenceUnitInfo .getManagedClassNames ();
95+ }
96+
97+ @ Override
98+ public URL getPersistenceUnitRootUrl () {
99+ return persistenceUnitRootUrl ;
100+ }
101+
102+ };
103+ });
60104 }
61105
62- public static AotMetamodel hibernateModel (String persistenceUnit , Class <?>... types ) {
63- return new AotMetamodel (persistenceUnit , Set .of (types ));
106+ public AotMetamodel (PersistenceUnitInfo unitInfo ) {
107+ this .entityManagerFactory = init (() -> new PersistenceUnitInfoDescriptor (unitInfo ));
108+ }
109+
110+ static Lazy <EntityManagerFactory > init (Supplier <PersistenceUnitInfoDescriptor > unitInfo ) {
111+
112+ return Lazy .of (() -> new EntityManagerFactoryBuilderImpl (unitInfo .get (),
113+ Map .of (JdbcSettings .DIALECT , H2Dialect .class .getName (), //
114+ JdbcSettings .ALLOW_METADATA_ON_BOOT , "false" , //
115+ JdbcSettings .CONNECTION_PROVIDER , new UserSuppliedConnectionProviderImpl ()))
116+ .build ());
117+ }
118+
119+ private Metamodel getMetamodel () {
120+ return getEntityManagerFactory ().getMetamodel ();
64121 }
65122
66123 public <X > EntityType <X > entity (Class <X > cls ) {
67- return metamodel . get ().entity (cls );
124+ return getMetamodel ().entity (cls );
68125 }
69126
70127 @ Override
71128 public EntityType <?> entity (String s ) {
72- return metamodel . get ().entity (s );
129+ return getMetamodel ().entity (s );
73130 }
74131
75132 public <X > ManagedType <X > managedType (Class <X > cls ) {
76- return metamodel . get ().managedType (cls );
133+ return getMetamodel ().managedType (cls );
77134 }
78135
79136 public <X > EmbeddableType <X > embeddable (Class <X > cls ) {
80- return metamodel . get ().embeddable (cls );
137+ return getMetamodel ().embeddable (cls );
81138 }
82139
83140 public Set <ManagedType <?>> getManagedTypes () {
84- return metamodel . get ().getManagedTypes ();
141+ return getMetamodel ().getManagedTypes ();
85142 }
86143
87144 public Set <EntityType <?>> getEntities () {
88- return metamodel . get ().getEntities ();
145+ return getMetamodel ().getEntities ();
89146 }
90147
91148 public Set <EmbeddableType <?>> getEmbeddables () {
92- return metamodel . get ().getEmbeddables ();
149+ return getMetamodel ().getEmbeddables ();
93150 }
94151
95152 public EntityManager entityManager () {
@@ -100,32 +157,4 @@ public EntityManagerFactory getEntityManagerFactory() {
100157 return entityManagerFactory .get ();
101158 }
102159
103- EntityManagerFactory init () {
104-
105- MutablePersistenceUnitInfo persistenceUnitInfo = new MutablePersistenceUnitInfo () {
106- @ Override
107- public ClassLoader getNewTempClassLoader () {
108- return new SimpleThrowawayClassLoader (this .getClass ().getClassLoader ());
109- }
110-
111- @ Override
112- public void addTransformer (ClassTransformer classTransformer ) {
113- // just ignore it
114- }
115- };
116-
117- persistenceUnitInfo .setPersistenceUnitName (persistenceUnit );
118- this .managedTypes .stream ().map (Class ::getName ).forEach (persistenceUnitInfo ::addManagedClassName );
119-
120- persistenceUnitInfo .setPersistenceProviderClassName (HibernatePersistenceProvider .class .getName ());
121-
122- return new EntityManagerFactoryBuilderImpl (new PersistenceUnitInfoDescriptor (persistenceUnitInfo ) {
123- @ Override
124- public List <String > getManagedClassNames () {
125- return persistenceUnitInfo .getManagedClassNames ();
126- }
127- }, Map .of ("hibernate.dialect" , "org.hibernate.dialect.H2Dialect" , "hibernate.boot.allow_jdbc_metadata_access" ,
128- "false" )).build ();
129- }
130-
131160}
0 commit comments