All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nablarch.common.dao.EntityMeta Maven / Gradle / Ivy

The newest version!
package nablarch.common.dao;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Table;

import nablarch.core.beans.BeanUtil;
import nablarch.core.log.Logger;
import nablarch.core.log.LoggerManager;
import nablarch.core.repository.SystemRepository;
import nablarch.core.util.StringUtil;
import nablarch.core.util.annotation.Published;

/**
 * Entityクラスのメタデータを保持するクラス。
 *
 * @author kawasima
 * @author Hisaaki Shioiri
 */
@Published(tag = "architect")
public class EntityMeta {

    /** ロガー */
    private static final Logger LOGGER = LoggerManager.get(EntityMeta.class);

    /** テーブル名 */
    private final String tableName;

    /** スキーマ名 */
    private final String schemaName;

    /** カラムのメタ情報 */
    private final List columnMetaList;

    /** ID(主キー)カラムのリスト */
    private final List idColumns;

    /** バージョンカラム */
    private final ColumnMeta versionColumn;

    /** 採番カラム */
    private final ColumnMeta generatedValueColumn;

    /** 主キー検索が実行できるか否か */
    private boolean enableFindById = true;

    /**
     * コンストラクタ。
     *
     * @param entityClass エンティティクラス
     */
    public EntityMeta(final Class entityClass) {

        final Access access = entityClass.getAnnotation(Access.class);
        final JpaAnnotationParamFactory jpaAnnotationParamFactory;
        if (access != null && access.value() == AccessType.FIELD) {
            jpaAnnotationParamFactory = new FieldBasedJpaAnnotationParamFactory();
        } else {
            jpaAnnotationParamFactory = new GetterBasedJpaAnnotationParamFactory();
        }

        tableName = findTableName(entityClass);

        schemaName = findSchemaName(entityClass);

        final PropertyDescriptor[] propertyDescriptors = BeanUtil.getPropertyDescriptors(entityClass);

        columnMetaList = new ArrayList(propertyDescriptors.length);
        idColumns = new ArrayList(propertyDescriptors.length);

        ColumnMeta tempVersionColumn = null;
        ColumnMeta tempGeneratedValueColumn = null;
        for (PropertyDescriptor pd : propertyDescriptors) {
            final JpaAnnotationParam jpaAnnotationParam = jpaAnnotationParamFactory.create(tableName, pd, entityClass);
            if (jpaAnnotationParam.isJoinColumn()) {
                continue;
            }

            final ColumnMeta meta = new ColumnMeta(this, jpaAnnotationParam);
            if (!meta.isTransient()) {
                columnMetaList.add(meta);
            }
            if (meta.isIdColumn()) {
                idColumns.add(meta);
            }
            if (meta.isVersion()) {
                if (tempVersionColumn != null) {
                    throw new IllegalEntityException(
                            "version column must be single definition. class name = " + entityClass.getName());
                }
                tempVersionColumn = meta;
            }
            if (meta.isGeneratedValue()) {
                if (tempGeneratedValueColumn != null) {
                    throw new IllegalEntityException(
                            "Generated value column must be single definition. class name = " + entityClass.getName());
                }
                tempGeneratedValueColumn = meta;
            }
        }
        versionColumn = tempVersionColumn;
        generatedValueColumn = tempGeneratedValueColumn;

        try {
            sortIdColumns();
        } catch (RuntimeException e) {
            // 5u21からsortIdColumns内部で例外が発生したときに、ログを出力するように変更した。
            // このログの出力を無効化したい場合は環境設定ファイルに、以下の記述を追加すること。
            // nablarch.entityMeta.hideCauseExceptionLog=true
            if (isShowCauseExceptionLog()) {
                LOGGER.logWarn("Failed to process sortIdColumns.", e);
            }
            enableFindById = false;
        }
    }

    /**
     * 原因となった例外をログに出力するかどうか判定する。
     * 

* デフォルトではログを出力しない。
* プロパティnablarch.entityMeta.hideCauseExceptionLogにtrueが設定されていた場合はログ出力を抑制する。 * * @return ログを出力するなら true */ private boolean isShowCauseExceptionLog() { return !SystemRepository.getBoolean("nablarch.entityMeta.hideCauseExceptionLog"); } /** * エンティティクラスからテーブル名を取得する。 *

* {@link Table}アノテーションが設定されており、{@link Table#name()}が設定されている場合は、 * その値をテーブル名とする。 * これに該当しない場合は、エンティティクラスのクラス名をスネークケース(全て大文字)に変換した値をテーブル名とする。 * * @param entityClass エンティティクラス。 * @return テーブル名 */ private static String findTableName(Class entityClass) { final Table table = entityClass.getAnnotation(Table.class); if (table != null && StringUtil.hasValue(table.name())) { return table.name(); } else { return NamingConversionUtil.deCamelize(entityClass.getSimpleName()); } } /** * エンティティクラスからスキーマ名を取得する。 * * {@link Table#schema()}が設定されている場合、その値をスキーマ名として返す。 * それ以外の場合は、{@code null}を返す。 * * @param entityClass エンティティクラス。 * @return スキーマ名 */ private static String findSchemaName(final Class entityClass) { final Table table = entityClass.getAnnotation(Table.class); if (table == null) { return null; } final String schema = table.schema(); return StringUtil.isNullOrEmpty(schema) ? null : schema; } /** * IDカラム(主キーカラム)のリストを返す。 * * @return カラムメタデータリスト */ public List getIdColumns() { return new ArrayList(idColumns); } /** * 全カラムのリストを返す。 * * @return 全カラムメタデータリスト */ public List getAllColumns() { return new ArrayList(columnMetaList); } /** * バージョンカラムを返す。 * * @return バージョンカラム情報 */ public ColumnMeta getVersionColumn() { return versionColumn; } /** * 採番カラムを返す。 * @return 採番カラム情報 */ public ColumnMeta getGeneratedValueColumn() { return generatedValueColumn; } /** * テーブル名を返す。 * * @return テーブル名 */ public String getTableName() { return tableName; } /** * スキーマ名を返す。 * @return スキーマ名 */ public String getSchemaName() { return schemaName; } /** * IDカラムから情報が取得可能か否か。 * * @return IDからカラム情報が取得可能な場合true */ public boolean canFindById() { return enableFindById; } /** * Primary keyの順番をデータベースの定義順にソートする。 */ protected void sortIdColumns() { final Map primaryKeyOrder = DatabaseUtil.getPrimaryKey(tableName); Collections.sort(idColumns, new Comparator() { @Override public int compare(final ColumnMeta cm1, final ColumnMeta cm2) { return primaryKeyOrder.get(cm1.getName().toUpperCase()) - primaryKeyOrder.get(cm2.getName().toUpperCase()); } }); } @Override public boolean equals(final Object another) { if (another == null || !(another instanceof EntityMeta)) { return false; } final EntityMeta anotherMeta = EntityMeta.class.cast(another); return this.tableName.equals(anotherMeta.tableName); } @Override public int hashCode() { return tableName.hashCode(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy