下面列出了怎么用javax.persistence.metamodel.Bindable的API类实例代码及写法,或者点击链接到github查看源代码。
public static boolean containsRelation(Object expr) {
if (expr instanceof Join) {
return true;
} else if (expr instanceof SingularAttribute) {
SingularAttribute<?, ?> attr = (SingularAttribute<?, ?>) expr;
return attr.isAssociation();
} else if (expr instanceof Path) {
Path<?> attrPath = (Path<?>) expr;
Bindable<?> model = attrPath.getModel();
Path<?> parent = attrPath.getParentPath();
return containsRelation(parent) || containsRelation(model);
} else {
// we may can do better here...
return false;
}
}
public Builder<X> getBuilder() {
if ( locked ) {
throw new IllegalStateException( "Type has been locked" );
}
return new Builder<X>() {
@Override
@SuppressWarnings("unchecked")
public void addAttribute(Attribute<X,?> attribute) {
declaredAttributes.put( attribute.getName(), attribute );
final Bindable.BindableType bindableType = ( ( Bindable ) attribute ).getBindableType();
switch ( bindableType ) {
case SINGULAR_ATTRIBUTE : {
declaredSingularAttributes.put( attribute.getName(), (SingularAttribute<X,?>) attribute );
break;
}
case PLURAL_ATTRIBUTE : {
declaredPluralAttributes.put(attribute.getName(), (PluralAttribute<X,?,?>) attribute );
break;
}
default : {
throw new AssertionFailure( "unknown bindable type: " + bindableType );
}
}
}
};
}
@SuppressWarnings({ "unchecked" })
public SingularAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathSource<O> pathSource,
SingularAttribute<? super O, ?> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
if ( Attribute.PersistentAttributeType.EMBEDDED == joinAttribute.getPersistentAttributeType() ) {
this.model = (Bindable<X>) joinAttribute;
}
else {
if ( javaType != null ) {
this.model = (Bindable<X>) criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType );
}
else {
this.model = (Bindable<X>) joinAttribute.getType();
}
}
}
public static boolean containsRelation(Object expr) {
if (expr instanceof Join) {
return true;
}
else if (expr instanceof SingularAttribute) {
SingularAttribute<?, ?> attr = (SingularAttribute<?, ?>) expr;
return attr.isAssociation();
}
else if (expr instanceof Path) {
Path<?> attrPath = (Path<?>) expr;
Bindable<?> model = attrPath.getModel();
Path<?> parent = attrPath.getParentPath();
return containsRelation(parent) || containsRelation(model);
}
else {
// we may can do better here...
return false;
}
}
@Override
@SuppressWarnings("unchecked")
protected ManagedType<? super X> locateManagedType() {
if ( getModel().getBindableType() == Bindable.BindableType.ENTITY_TYPE ) {
return (ManagedType<? super X>) getModel();
}
else if ( getModel().getBindableType() == Bindable.BindableType.SINGULAR_ATTRIBUTE ) {
final Type joinedAttributeType = ( (SingularAttribute) getAttribute() ).getType();
if ( !ManagedType.class.isInstance( joinedAttributeType ) ) {
throw new UnsupportedOperationException(
"Cannot further dereference attribute join [" + getPathIdentifier() + "] as its type is not a ManagedType"
);
}
return (ManagedType<? super X>) joinedAttributeType;
}
else if ( getModel().getBindableType() == Bindable.BindableType.PLURAL_ATTRIBUTE ) {
final Type elementType = ( (PluralAttribute) getAttribute() ).getElementType();
if ( !ManagedType.class.isInstance( elementType ) ) {
throw new UnsupportedOperationException(
"Cannot further dereference attribute join [" + getPathIdentifier() + "] (plural) as its element type is not a ManagedType"
);
}
return (ManagedType<? super X>) elementType;
}
return super.locateManagedType();
}
public Bindable<X> getModel() {
// the issue here is the parameterized type; X is the collection
// type (Map, Set, etc) while the "bindable" for a collection is the
// elements.
//
// TODO : throw exception instead?
return null;
}
static <T> Expression<T> toExpressionRecursively(From<?, ?> from, PropertyPath property, boolean isForSelection) {
Bindable<?> propertyPathModel;
Bindable<?> model = from.getModel();
String segment = property.getSegment();
if (model instanceof ManagedType) {
/*
* Required to keep support for EclipseLink 2.4.x. TODO: Remove once we drop that (probably Dijkstra M1)
* See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=413892
*/
propertyPathModel = (Bindable<?>) ((ManagedType<?>) model).getAttribute(segment);
} else {
propertyPathModel = from.get(segment).getModel();
}
if (requiresJoin(propertyPathModel, model instanceof PluralAttribute, !property.hasNext(), isForSelection)
&& !isAlreadyFetched(from, segment)) {
Join<?, ?> join = getOrCreateJoin(from, segment);
return (Expression<T>) (property.hasNext() ? toExpressionRecursively(join, property.next(), isForSelection)
: join);
} else {
Path<Object> path = from.get(segment);
return (Expression<T>) (property.hasNext() ? toExpressionRecursively(path, property.next()) : path);
}
}
private static boolean requiresJoin(@Nullable Bindable<?> propertyPathModel, boolean isPluralAttribute,
boolean isLeafProperty, boolean isForSelection) {
if (propertyPathModel == null && isPluralAttribute) {
return true;
}
if (!(propertyPathModel instanceof Attribute)) {
return false;
}
Attribute<?, ?> attribute = (Attribute<?, ?>) propertyPathModel;
if (!ASSOCIATION_TYPES.containsKey(attribute.getPersistentAttributeType())) {
return false;
}
// if this path is part of the select list we need to generate an explicit outer join in order to prevent Hibernate
// to use an inner join instead.
// see https://hibernate.atlassian.net/browse/HHH-12999.
if (isLeafProperty && !isForSelection && !attribute.isCollection()) {
return false;
}
Class<? extends Annotation> associationAnnotation = ASSOCIATION_TYPES.get(attribute.getPersistentAttributeType());
if (associationAnnotation == null) {
return true;
}
Member member = attribute.getJavaMember();
if (!(member instanceof AnnotatedElement)) {
return true;
}
Annotation annotation = AnnotationUtils.getAnnotation((AnnotatedElement) member, associationAnnotation);
return annotation == null ? true : (boolean) AnnotationUtils.getValue(annotation, "optional");
}
public Bindable<X> getModel() {
return model;
}
@Override
public Bindable<X> getModel() {
return getAttribute();
}
public Bindable<K> getModel() {
return mapKeyAttribute;
}
@SuppressWarnings({ "unchecked" })
public Bindable<Map<K, V>> getModel() {
// TODO : ok??? the attribute is in fact bindable, but its type signature is different
return (Bindable<Map<K, V>>) mapAttribute;
}