public XClass getClassWithIdClass(boolean evenIfSubclass) { if ( !evenIfSubclass && hasParents() ) { return null; } if ( clazz.isAnnotationPresent( IdClass.class ) ) { return clazz; } else { InheritanceState state = InheritanceState.getSuperclassInheritanceState( clazz, inheritanceStatePerClass ); if ( state != null ) { return state.getClassWithIdClass( true ); } else { return null; } } }
/** * 获取实体类ID Class * @param clazz * @return */ @SuppressWarnings("unchecked") public static Class<? extends Serializable> getDomainIDClass(Class<? extends BaseDomain> clazz){ /** * 如果是联合主键实体类则返回domainID,因为联合主键类必须实现getDomainID()方法 */ IdClass annotation = clazz.getAnnotation(IdClass.class); if (annotation != null) { return annotation.value(); } try { Field f = ReflectUtil.getDeclaredField(clazz, getDomainIDName(clazz)); if (f != null) { return (Class<? extends Serializable>) f.getType(); } } catch (Exception e) { e.printStackTrace(); throw createFindIdException(clazz, e); } throw createIDNotfoundException(clazz); }
/** * 获取ID字段 * @param clazz * @return */ @SuppressWarnings("unchecked") public static Field getIDfield(Class<? extends BaseDomain> clazz) { if (clazz.getAnnotation(IdClass.class) != null) { StringBuffer sb = new StringBuffer("按照约定含有"); sb.append(IdClass.class.getName()); sb.append("注解的domain不能有ID字段!!!只能有getDomainID()方法。"); throw new RuntimeException(sb.toString()); } Field[] fields = clazz.getDeclaredFields(); for (Field f:fields) { f.setAccessible(true); Annotation temp = f.getAnnotation(Id.class); if (temp == null) { continue; } return f; } if (clazz == BaseDomain.class) { return null; } return getIDfield((Class<? extends BaseDomain>)clazz.getSuperclass()); }
@SuppressWarnings("unchecked") public static Method getIDmethod(Class<? extends BaseDomain> clazz) { if (clazz.getAnnotation(IdClass.class) != null) { try { return clazz.getDeclaredMethod("getDomainID"); } catch (NoSuchMethodException e) { throw new RuntimeException("含有"+IdClass.class.getName()+ "的domain必须实现"+UnionKeyDomain.class.getName()+"接口!!!",e); } } Method[] methods = clazz.getDeclaredMethods(); for (Method m:methods) { Annotation aa = m.getAnnotation(Id.class); if (aa == null) { continue; } return m; } if (clazz == BaseDomain.class) { return null; } return getIDmethod((Class<? extends BaseDomain>)clazz.getSuperclass()); }
@Override public String[] extractIdPropertyNames(Object entity) { final IdClass idClassAnn = entity.getClass().getAnnotation(IdClass.class); if (idClassAnn != null) { final Class<?> entityClass = idClassAnn.value(); final List<String> retVal = new ArrayList<>(3); ReflectionUtils.doWithFields(entityClass, (f)-> { if (! Modifier.isStatic(f.getModifiers())) { retVal.add(f.getName()); } }); return retVal.toArray(new String[retVal.size()]); } else { final ClassMetadata classMetadata = factory.getClassMetadata(entity.getClass()); final String propertyName = classMetadata.getIdentifierPropertyName(); return propertyName != null ? new String[]{propertyName} : null; } }
private Map<Field, Object> getIdProperties(String[] propertyNames, Serializable id, Object entity) { final IdClass idClassAnn = entity.getClass().getAnnotation(IdClass.class); final boolean isComposite = idClassAnn != null; if (! isComposite) { return Collections.singletonMap(ReflectionUtils.findField(entity.getClass(), propertyNames[0]), id); } else { // We need to extract the id properties from the composite object final Map<Field, Object> retVal = new LinkedHashMap<>(propertyNames.length); final Class<?> entityIdClass = idClassAnn.value(); ReflectionUtils.doWithFields(entityIdClass, (f)-> { if (! Modifier.isStatic(f.getModifiers()) && fieldFilter.test(f)) { final String fieldName = f.getName(); retVal.put(f, ReflectionUtil.get(entity, fieldName)); } }); return retVal; } }
@SuppressWarnings({ "unchecked", "rawtypes" }) public static Class<? extends Serializable> primaryKeyClass(Class<?> entityClass) { if (entityClass.isAnnotationPresent(IdClass.class)) { return entityClass.getAnnotation(IdClass.class).value(); // Serializablity isn't required, could cause // problems } Class clazz = PersistenceUnitDescriptorProvider.getInstance().primaryKeyIdClass(entityClass); if (clazz != null) { return clazz; } Property<Serializable> property = primaryKeyProperty(entityClass); return property.getJavaClass(); }
private static boolean isIdClassPkOfTheAssociatedEntity( InheritanceState.ElementsToProcess elementsToProcess, XClass compositeClass, PropertyData inferredData, PropertyData baseInferredData, AccessType propertyAccessor, Map<XClass, InheritanceState> inheritanceStatePerClass, Mappings mappings) { if ( elementsToProcess.getIdPropertyCount() == 1 ) { final PropertyData idPropertyOnBaseClass = getUniqueIdPropertyFromBaseClass( inferredData, baseInferredData, propertyAccessor, mappings ); final InheritanceState state = inheritanceStatePerClass.get( idPropertyOnBaseClass.getClassOrElement() ); if ( state == null ) { return false; //while it is likely a user error, let's consider it is something that might happen } final XClass associatedClassWithIdClass = state.getClassWithIdClass( true ); if ( associatedClassWithIdClass == null ) { //we cannot know for sure here unless we try and find the @EmbeddedId //Let's not do this thorough checking but do some extra validation final XProperty property = idPropertyOnBaseClass.getProperty(); return property.isAnnotationPresent( ManyToOne.class ) || property.isAnnotationPresent( OneToOne.class ); } else { final XClass idClass = mappings.getReflectionManager().toXClass( associatedClassWithIdClass.getAnnotation( IdClass.class ).value() ); return idClass.equals( compositeClass ); } } else { return false; } }
private IdClass getIdClass(Element tree, XMLContext.Default defaults) { Element element = tree == null ? null : tree.element( "id-class" ); if ( element != null ) { Attribute attr = element.attribute( "class" ); if ( attr != null ) { AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class ); Class clazz; try { clazz = ReflectHelper.classForName( XMLContext.buildSafeClassName( attr.getValue(), defaults ), this.getClass() ); } catch ( ClassNotFoundException e ) { throw new AnnotationException( "Unable to find id-class: " + attr.getValue(), e ); } ad.setValue( "value", clazz ); return AnnotationFactory.create( ad ); } else { throw new AnnotationException( "id-class without class. " + SCHEMA_VALIDATION ); } } else if ( defaults.canUseJavaAnnotations() ) { return getPhysicalAnnotation( IdClass.class ); } else { return null; } }
private boolean shouldOmitPropertyWithCompositeKey(Map<String, String> propertyAttributes) { // Extract simple type name of the relationship types boolean isManyToOneRel = Boolean.parseBoolean(propertyAttributes.get("many-to-one")); boolean isOneToOneRel = Boolean.parseBoolean(propertyAttributes.get("one-to-one")); boolean isNToManyRel = Boolean.parseBoolean(propertyAttributes.get("n-to-many")); if (isManyToOneRel || isNToManyRel || isOneToOneRel) { String rightHandSideType; // Obtain the class name of the other/right-hand side of the relationship. if (isOneToOneRel || isManyToOneRel) { rightHandSideType = propertyAttributes.get("type"); } else { rightHandSideType = propertyAttributes.get("parameterized-type"); } JavaClassSource javaClass = getJavaClass(rightHandSideType); for (Member<?> member : javaClass.getMembers()) { // FORGEPLUGINS-120 Ensure that properties with composite keys are detected and omitted from generation if (member.hasAnnotation(Id.class) && !javaClass.hasAnnotation(IdClass.class)) { return false; } if (member.hasAnnotation(EmbeddedId.class)) { return true; } } } return false; }
/** * If exactly one field is annotated with @EmbeddedId or the class is * annotated with @IdClass, we consider the entity a compound entity (= the * table has a compound key). Otherwise if exactly one field is annotated * with @Id, we consider the entity a simple entity (= the table has a * primary key). * * @param entityClazz * @return what type of entity the annotated class is (simple or compound). */ public static <T> SupportedEntityType inspectEntityClass(Class<T> entityClazz) { Preconditions.checkNotNull(entityClazz); boolean idClass = AnnotationUtils.isAnnotationDeclaredLocally(IdClass.class, entityClazz); Field id = findPrimaryKeyField(entityClazz); Field embeddedId = findCompoundKeyField(entityClazz); if (idClass) { if (embeddedId != null) { throw new IllegalStateException("@IdClass and @EmbeddedId are mutually exclusive."); } return SupportedEntityType.COMPOUND_IDCLASS; } if (id != null && embeddedId != null) { throw new IllegalStateException("@Id and @EmbeddedId are mutually exclusive"); } else if (id == null && embeddedId == null) { throw new IllegalStateException("Entity needs at least one of @Id, @EmbeddedId, or @IdClass"); } else if (id != null) { return SupportedEntityType.SIMPLE; } else if (embeddedId != null) { /* * If the field is annotated with @EmbeddedId, then the type of the * field must have been annotated with @Embeddable. */ Class<?> embeddedType = embeddedId.getType(); boolean annotatedWithEmbeddable = false; for (Annotation annotation : embeddedType.getDeclaredAnnotations()) { if (annotation.annotationType().equals(javax.persistence.Embeddable.class)) { annotatedWithEmbeddable = true; break; } } if (!annotatedWithEmbeddable) { throw new IllegalStateException("Embedded entity isn't annotated with @Embeddable."); } return SupportedEntityType.COMPOUND; } else { return SupportedEntityType.NONE; } }