/** * 一対多の関連を処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ * @param oneToMany 一対多関連 */ protected void doOneToMany( PropertyMeta propertyMeta, Field field, EntityMeta entityMeta, OneToMany oneToMany) { propertyMeta.setRelationshipType(RelationshipType.ONE_TO_MANY); if (!List.class.isAssignableFrom(field.getType())) { throw new OneToManyNotListRuntimeException(entityMeta.getName(), propertyMeta.getName()); } Class<?> relationshipClass = ReflectionUtil.getElementTypeOfList(field.getGenericType()); if (relationshipClass == null) { throw new OneToManyNotGenericsRuntimeException(entityMeta.getName(), propertyMeta.getName()); } if (relationshipClass.getAnnotation(Entity.class) == null) { throw new RelationshipNotEntityRuntimeException( entityMeta.getName(), propertyMeta.getName(), relationshipClass); } propertyMeta.setRelationshipClass(relationshipClass); String mappedBy = oneToMany.mappedBy(); if (!StringUtil.isEmpty(mappedBy)) { if (propertyMeta.getJoinColumnMetaList().size() > 0) { throw new BothMappedByAndJoinColumnRuntimeException( entityMeta.getName(), propertyMeta.getName()); } propertyMeta.setMappedBy(mappedBy); } else { throw new MappedByMandatoryRuntimeException(entityMeta.getName(), propertyMeta.getName()); } }
/** * 識別子メタデータを処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ */ protected void doId(PropertyMeta propertyMeta, Field field, EntityMeta entityMeta) { propertyMeta.setId(field.getAnnotation(Id.class) != null); GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class); if (generatedValue == null) { return; } GenerationType generationType = generatedValue.strategy(); propertyMeta.setGenerationType(generationType); switch (generationType) { case AUTO: doIdentityIdGenerator(propertyMeta, entityMeta); doSequenceIdGenerator(propertyMeta, generatedValue, entityMeta); doTableIdGenerator(propertyMeta, generatedValue, entityMeta); break; case IDENTITY: doIdentityIdGenerator(propertyMeta, entityMeta); break; case SEQUENCE: if (!doSequenceIdGenerator(propertyMeta, generatedValue, entityMeta)) { throw new IdGeneratorNotFoundRuntimeException( entityMeta.getName(), propertyMeta.getName(), generatedValue.generator()); } break; case TABLE: if (!doTableIdGenerator(propertyMeta, generatedValue, entityMeta)) { throw new IdGeneratorNotFoundRuntimeException( entityMeta.getName(), propertyMeta.getName(), generatedValue.generator()); } break; } }
/** * 一対一の関連を処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ * @param oneToOne 一対一関連 */ protected void doOneToOne( PropertyMeta propertyMeta, Field field, EntityMeta entityMeta, OneToOne oneToOne) { propertyMeta.setRelationshipType(RelationshipType.ONE_TO_ONE); Class<?> relationshipClass = field.getType(); if (relationshipClass.getAnnotation(Entity.class) == null) { throw new RelationshipNotEntityRuntimeException( entityMeta.getName(), propertyMeta.getName(), relationshipClass); } propertyMeta.setRelationshipClass(relationshipClass); String mappedBy = oneToOne.mappedBy(); if (!StringUtil.isEmpty(mappedBy)) { if (propertyMeta.getJoinColumnMetaList().size() > 0) { throw new BothMappedByAndJoinColumnRuntimeException( entityMeta.getName(), propertyMeta.getName()); } propertyMeta.setMappedBy(mappedBy); } }
/** * 時制の種別を処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ */ protected void doTemporal(PropertyMeta propertyMeta, Field field, EntityMeta entityMeta) { if (propertyMeta.getPropertyClass() != java.util.Date.class && propertyMeta.getPropertyClass() != Calendar.class) { return; } Temporal temporal = field.getAnnotation(Temporal.class); if (temporal == null) { throw new TemporalTypeNotSpecifiedRuntimeException( entityMeta.getName(), propertyMeta.getName()); } propertyMeta.setTemporalType(temporal.value()); }
/** * フェッチタイプを処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ */ protected void doFetchType( final PropertyMeta propertyMeta, final Field field, final EntityMeta entityMeta) { final Basic basic = field.getAnnotation(Basic.class); if (basic == null) { propertyMeta.setFetchType(FetchType.EAGER); return; } if (propertyMeta.isId() && basic.fetch() == FetchType.LAZY) { throw new LazyFetchSpecifiedRuntimeException(entityMeta.getName(), propertyMeta.getName()); } propertyMeta.setFetchType(basic.fetch()); }
/** * 関連用のクラスを返します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ * @return 関連用のクラス * @throws OneToManyNotGenericsRuntimeException 一対多の関連がジェネリクスのリストではない場合。 */ protected Class<?> getRelationshipClass( PropertyMeta propertyMeta, Field field, EntityMeta entityMeta) throws OneToManyNotGenericsRuntimeException { Class<?> clazz = field.getType(); if (List.class.isAssignableFrom(clazz)) { clazz = ReflectionUtil.getElementTypeOfList(field.getGenericType()); if (clazz == null) { throw new OneToManyNotGenericsRuntimeException( entityMeta.getName(), propertyMeta.getName()); } } return clazz; }
/** * 多対一の関連を処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ * @param manyToOne 多対一関連 */ protected void doManyToOne( PropertyMeta propertyMeta, Field field, EntityMeta entityMeta, @SuppressWarnings("unused") ManyToOne manyToOne) { propertyMeta.setRelationshipType(RelationshipType.MANY_TO_ONE); Class<?> relationshipClass = field.getType(); if (relationshipClass.getAnnotation(Entity.class) == null) { throw new RelationshipNotEntityRuntimeException( entityMeta.getName(), propertyMeta.getName(), relationshipClass); } propertyMeta.setRelationshipClass(relationshipClass); }
/** * 関連を処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ * @param annotation 関連のアノテーション */ protected void doRelationship( PropertyMeta propertyMeta, Field field, EntityMeta entityMeta, Object annotation) { doJoinColumn(propertyMeta, field, entityMeta); if (OneToOne.class.isInstance(annotation)) { doOneToOne(propertyMeta, field, entityMeta, OneToOne.class.cast(annotation)); } else if (OneToMany.class.isInstance(annotation)) { doOneToMany(propertyMeta, field, entityMeta, OneToMany.class.cast(annotation)); } else if (ManyToOne.class.isInstance(annotation)) { doManyToOne(propertyMeta, field, entityMeta, ManyToOne.class.cast(annotation)); } else { throw new UnsupportedRelationshipRuntimeException( entityMeta.getName(), propertyMeta.getName()); } }
/** * バージョンチェック用かどうかを処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ */ protected void doVersion( PropertyMeta propertyMeta, Field field, @SuppressWarnings("unused") EntityMeta entityMeta) { if (field.getAnnotation(Version.class) == null) { return; } Class<?> clazz = ClassUtil.getWrapperClassIfPrimitive(field.getType()); if (clazz != Integer.class && clazz != Long.class && clazz != int.class && clazz != long.class) { throw new VersionPropertyNotNumberRuntimeException( entityMeta.getName(), propertyMeta.getName()); } propertyMeta.setVersion(true); }
/** set句に設定されるプロパティの準備をします。 */ protected void prepareTargetProperties() { for (final PropertyMeta propertyMeta : entityMeta.getAllColumnPropertyMeta()) { final String propertyName = propertyMeta.getName(); if (propertyMeta.isId() || !propertyMeta.getColumnMeta().isUpdatable()) { continue; } if (propertyMeta.isVersion() && !includeVersion) { continue; } if (!includesProperties.isEmpty() && !includesProperties.contains(propertyName)) { continue; } if (excludesProperties.contains(propertyName)) { continue; } targetProperties.add(propertyMeta); } }
public SequenceDesc getSequenceDesc(EntityMeta entityMeta, PropertyMeta propertyMeta) { GenerationType generationType = propertyMeta.getGenerationType(); if (generationType == GenerationType.AUTO) { generationType = dialect.getDefaultGenerationType(); } if (generationType == GenerationType.SEQUENCE) { if (!dialect.supportsSequence()) { throw new UnsupportedGenerationTypeRuntimeException( GenerationType.SEQUENCE, entityMeta.getName(), propertyMeta.getName()); } SequenceGenerator generator = getSequenceGenerator(entityMeta, propertyMeta); SequenceDesc sequenceDesc = new SequenceDesc(); String sequenceName = getSequenceName(entityMeta, propertyMeta, generator); sequenceDesc.setSequenceName(sequenceName); sequenceDesc.setInitialValue(generator.initialValue()); sequenceDesc.setAllocationSize(generator.allocationSize()); sequenceDesc.setDataType(getDataType(propertyMeta)); return sequenceDesc; } return null; }
/** * JoinColumnを処理します。 * * @param propertyMeta プロパティメタデータ * @param field フィールド * @param entityMeta エンティティメタデータ */ protected void doJoinColumn(PropertyMeta propertyMeta, Field field, EntityMeta entityMeta) { JoinColumn joinColumn = field.getAnnotation(JoinColumn.class); if (joinColumn != null) { JoinColumnMeta meta = new JoinColumnMeta(joinColumn.name(), joinColumn.referencedColumnName()); propertyMeta.addJoinColumnMeta(meta); } else { JoinColumns joinColumns = field.getAnnotation(JoinColumns.class); if (joinColumns != null) { JoinColumn[] array = joinColumns.value(); for (int i = 0; i < array.length; i++) { JoinColumn jc = array[i]; JoinColumnMeta meta = new JoinColumnMeta(jc.name(), jc.referencedColumnName()); if (i > 0 && (meta.getName() == null || meta.getReferencedColumnName() == null)) { throw new JoinColumnNameAndReferencedColumnNameMandatoryRuntimeException( entityMeta.getName(), propertyMeta.getName(), i + 1); } propertyMeta.addJoinColumnMeta(meta); } } } }
/** * {@link ValueType}を処理します。 * * @param propertyMeta プロパティメタデータ * @param entityMeta エンティティメタデータ */ @SuppressWarnings("unchecked") protected void doValueType(final PropertyMeta propertyMeta, final EntityMeta entityMeta) { final Class<?> propertyClass = propertyMeta.getPropertyClass(); final ValueType valueType = valueTypes.get(propertyClass); if (valueType != null) { propertyMeta.setValueType(valueType); return; } if (propertyClass == String.class) { if (propertyMeta.isLob()) { propertyMeta.setValueType(ValueTypes.CLOB); } else { propertyMeta.setValueType(ValueTypes.STRING); } return; } if (propertyClass == byte[].class) { if (propertyMeta.isLob()) { propertyMeta.setValueType(ValueTypes.BLOB); } else { propertyMeta.setValueType(ValueTypes.BYTE_ARRAY); } return; } if (propertyClass == Date.class) { switch (propertyMeta.getTemporalType()) { case DATE: propertyMeta.setValueType(ValueTypes.DATE_SQLDATE); return; case TIME: propertyMeta.setValueType(ValueTypes.DATE_TIME); return; case TIMESTAMP: propertyMeta.setValueType(ValueTypes.DATE_TIMESTAMP); return; } } if (propertyClass == Calendar.class) { switch (propertyMeta.getTemporalType()) { case DATE: propertyMeta.setValueType(ValueTypes.CALENDAR_SQLDATE); return; case TIME: propertyMeta.setValueType(ValueTypes.CALENDAR_TIME); return; case TIMESTAMP: propertyMeta.setValueType(ValueTypes.CALENDAR_TIMESTAMP); return; } } if (propertyClass.isEnum()) { if (propertyMeta.getEnumType() == null) { propertyMeta.setValueType(ValueTypes.getValueType(propertyClass)); return; } switch (propertyMeta.getEnumType()) { case ORDINAL: propertyMeta.setValueType(ValueTypes.getEnumOrdinalValueType(propertyClass)); return; case STRING: propertyMeta.setValueType(ValueTypes.getEnumStringValueType(propertyClass)); return; } } final ValueType userDefinedValueType = ValueTypes.createUserDefineValueType(propertyClass); if (userDefinedValueType != null) { propertyMeta.setValueType(userDefinedValueType); return; } if (Serializable.class.isAssignableFrom(propertyClass)) { if (propertyMeta.isLob()) { propertyMeta.setValueType(ValueTypes.SERIALIZABLE_BLOB); } else { propertyMeta.setValueType(ValueTypes.SERIALIZABLE_BYTE_ARRAY); } return; } throw new UnsupportedPropertyTypeRuntimeException( entityMeta.getName(), propertyMeta.getName(), propertyMeta.getPropertyClass()); }