6

一部の JPA アノテーションでは、エラーが発生しやすい文字列の代わりにフィールド名をコード内で直接使用したいと考えています。

@javax.persistence.OrderBy(value = User_.registrationDate.getName())
public List<PlugConfig> getPlugConfigs() { ... }

ただし、名前を取得するには、定数式ではない関数を使用する必要があるため、上記はコンパイルされません (User_ は JPA @StaticMetamodel で生成されます)。

これに何らかの方法でメタモデルを使用することは可能ですか、それとも直接の文字列定数に固執する必要がありますか? このようなメタモデルの文字列定数を自動的に生成する方法はありますか? (生成には maven-processor-plugin を使用しています)

4

2 に答える 2

5

これで、メタモデル クラスのすべてのフィールドに対して 2 つのフィールドを取得できます。次に例を示します。

public static final String _registrationDate="registrationDate";
public static volatile SingularAttribute<User, Date> registrationDate;   

これを機能させるために、JPAMetaModelEntityProcessor のコードを再利用しました (残念ながら、このクラスを単純に拡張すると問題が発生しました)。このメソッドを追加しました:

    private void addFieldsNamesAsStrings(MetaEntity entity) {
    if (entity instanceof AnnotationMetaEntity) {

        AnnotationMetaEntity aentity = (AnnotationMetaEntity) entity;
        List<MetaAttribute> newMembers = new ArrayList<MetaAttribute>();
        for (final MetaAttribute ma : entity.getMembers()) {

            MetaAttribute nma = new AnnotationMetaAttribute(aentity, null,
                    null) {
                public String getDeclarationString() {
                    return new StringBuilder()
                            .append("public static final String ")
                            .append(getPropertyName()).append("=\""+ma.getPropertyName()+"\";")
                            .toString();
                }

                @Override
                public String getPropertyName() {
                    return "_"+ma.getPropertyName();
                }

                @Override
                public String getMetaType() {

                    return null;
                }

            };
            newMembers.add(nma);

            aentity.mergeInMembers(newMembers);
        }
    }

}

すべての発生の前に私が呼び出した

ClassWriter.writeFile(entity, context);

対応する Maven 構成:

        <plugin>
            <groupId>org.bsc.maven</groupId>
            <artifactId>maven-processor-plugin</artifactId>
            <executions>
                <execution>
                    <id>process</id>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <phase>generate-sources</phase>
                    <configuration>
                        <processors>
                            <processor>
                                com.company.MyProcessor
                  </processor>
                        </processors>
                        <outputDirectory>target/modelgen/src/main/java</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
于 2012-06-02T20:23:53.253 に答える
0

私は試していませんが、完全に他のコンテキスト(JPAではない)で読んだことから、試すことができます:

  • カスタム アノテーション (RetentionPolicy.SOURCE) を指定し、問題のエンティティ クラスにアノテーションを付けます (または、@Entity アノテーションに依存することもできます)。
  • 静的フィールドを持つクラスを作成するアノテーション プロセッサを作成する

例えば

public class UserConstants{
    public static final String REGISTRATION_DATE = User_.registrationDate.getName(); 
}

それはただの考えです。このケースに該当するかどうかはわかりません。

于 2012-05-31T20:59:32.700 に答える