16
16
package org .springframework .data .jpa .util ;
17
17
18
18
import java .util .Collection ;
19
+ import java .util .EnumSet ;
19
20
import java .util .Map ;
20
21
import java .util .Optional ;
22
+ import java .util .Set ;
21
23
import java .util .concurrent .ConcurrentHashMap ;
22
24
25
+ import javax .persistence .Embeddable ;
23
26
import javax .persistence .metamodel .EntityType ;
24
27
import javax .persistence .metamodel .ManagedType ;
25
28
import javax .persistence .metamodel .Metamodel ;
26
29
import javax .persistence .metamodel .SingularAttribute ;
30
+ import javax .persistence .metamodel .Type .PersistenceType ;
27
31
32
+ import org .springframework .core .annotation .AnnotatedElementUtils ;
28
33
import org .springframework .data .util .Lazy ;
29
34
import org .springframework .data .util .StreamUtils ;
30
35
import org .springframework .util .Assert ;
39
44
public class JpaMetamodel {
40
45
41
46
private static final Map <Metamodel , JpaMetamodel > CACHE = new ConcurrentHashMap <>(4 );
47
+ private static final Set <PersistenceType > ENTITY_OR_MAPPED_SUPERCLASS = EnumSet .of (PersistenceType .ENTITY ,
48
+ PersistenceType .MAPPED_SUPERCLASS );
42
49
43
50
private final Metamodel metamodel ;
44
51
45
52
private Lazy <Collection <Class <?>>> managedTypes ;
53
+ private Lazy <Collection <Class <?>>> jpaEmbeddables ;
46
54
47
55
/**
48
56
* Creates a new {@link JpaMetamodel} for the given JPA {@link Metamodel}.
@@ -54,10 +62,17 @@ private JpaMetamodel(Metamodel metamodel) {
54
62
Assert .notNull (metamodel , "Metamodel must not be null!" );
55
63
56
64
this .metamodel = metamodel ;
65
+
57
66
this .managedTypes = Lazy .of (() -> metamodel .getManagedTypes ().stream () //
58
67
.map (ManagedType ::getJavaType ) //
59
68
.filter (it -> it != null ) //
60
69
.collect (StreamUtils .toUnmodifiableSet ()));
70
+
71
+ this .jpaEmbeddables = Lazy .of (() -> metamodel .getEmbeddables ().stream () //
72
+ .map (ManagedType ::getJavaType )
73
+ .filter (it -> it != null )
74
+ .filter (it -> AnnotatedElementUtils .isAnnotated (it , Embeddable .class ))
75
+ .collect (StreamUtils .toUnmodifiableSet ()));
61
76
}
62
77
63
78
public static JpaMetamodel of (Metamodel metamodel ) {
@@ -96,6 +111,27 @@ public boolean isSingleIdAttribute(Class<?> entity, String name, Class<?> attrib
96
111
.orElse (false );
97
112
}
98
113
114
+ /**
115
+ * Returns whether the given type is considered a mapped type, i.e. an actually JPA persisted entity, mapped
116
+ * superclass or native JPA embeddable.
117
+ *
118
+ * @param entity must not be {@literal null}.
119
+ * @return
120
+ */
121
+ public boolean isMappedType (Class <?> entity ) {
122
+
123
+ Assert .notNull (entity , "Type must not be null!" );
124
+
125
+ if (!isJpaManaged (entity )) {
126
+ return false ;
127
+ }
128
+
129
+ ManagedType <?> managedType = metamodel .managedType (entity );
130
+
131
+ return !managedType .getPersistenceType ().equals (PersistenceType .EMBEDDABLE )
132
+ || jpaEmbeddables .get ().contains (entity );
133
+ }
134
+
99
135
/**
100
136
* Wipes the static cache of {@link Metamodel} to {@link JpaMetamodel}.
101
137
*/
0 commit comments