简体   繁体   中英

How do I automatically generate column names as static final strings in JPA 2.0 metamodel?

In some JPA annotations I want to use field names directly in code in place of error-prone strings:

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

But the above won't compile because to get name I have to use function that is not constant expression (User_ is generated JPA @StaticMetamodel).

Is it possible to use metamodel for this in any way or have I stick to direct string constants? Is there any way to automatically generate such string constants for metamodel? (I am using maven-processor-plugin for generation)

Now I get two fields for every field in my metamodel class, for example:

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

To get this working I reused code from JPAMetaModelEntityProcessor (unfortunatelly there was problem with simply extending this class). I've added this method:

    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);
        }
    }

}

which I invoked before every occurance of

ClassWriter.writeFile(entity, context);

Corresponding maven configuration:

        <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>

I haven't tried but from what I've read in a completly other context (not JPA) you could try:

  • Specify a custom annotation (RetentionPolicy.SOURCE) and annotate your entity classes in question (or you could just rely on the @Entity annotation)
  • Write a annotation processor, which writes a class with static fields

Eg

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

It's just a thought. I don't know if it fits in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM