views:

95

answers:

1

I'm currently trying to "translate" the following Java class to an equivalent Scala class. It's part of a JavaEE6-application and i need it to use the JPA2 MetaModel.

import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;

@StaticMetamodel(Person.class)
public class Person_ {
  public static volatile SingularAttribute<Person, String> name;
}

A dissassembling of the compiled class file reveals the following information for the compiled file:

> javap Person_.class :
public class model.Person_ extends java.lang.Object{
  public static volatile javax.persistence.metamodel.SingularAttribute name;
  public model.Person_();
} 

So now i need an equivalent Scala file that has the same structure, as JPA depends on it, cause it resolves the attributes by reflection to make them accessible at runtime. So the main problem i think is that the attribute is static, but the Annotation has to be on an (Java)Object (i guess) My first naive attempt to create a Scala equivalent is the following:

@StaticMetamodel(classOf[Person])
class Person_

object Person_ {
  @volatile var name:SingularAttribute[Person, String] = _;
}

But the resulting classfile is far away from the Java one, so it doesn't work. When trying to access the attributes at runtime, e.g. "Person_.firstname", it resolves to null, i think JPA can't do the right reflection magic on the compiled classfile (the Java variant resolves to an instance of org.hibernate.ejb.metamodel.SingularAttributeImpl at runtime).

> javap Person_.class :
public class model.Person_ extends java.lang.Object implements scala.ScalaObject{
  public static final void name_$eq(javax.persistence.metamodel.SingularAttribute);
  public static final javax.persistence.metamodel.SingularAttribute name();
  public model.Person_();
}

> javap Person_$.class :
public final class model.Person__$ extends java.lang.Object implements scala.ScalaObject
  public static final model.Person__$ MODULE$;
  public static {};
  public javax.persistence.metamodel.SingularAttribute name();
  public void name_$eq(javax.persistence.metamodel.SingularAttribute);
}

So now what i'd like to know is if it's possible at all to create a Scala equivalent of the Java class? It seems to me that it's absolutely not, but maybe there is a workaround or something (except just using Java, but i want my app to be in Scala where possible)

Any ideas, anyone? Thanks in advance!

+1  A: 

As you can see Scala companion objects are compiled into separate classes following a singleton pattern (the only instance is hold in MODULE$). This is necessary, as they can inherit from other classes as well.

AFAIK there is no way in Scala to get the static method you need into Person. I'm not using JPA with Scala, so I can't say much about this. Probably some people in one of the Scala mailing lists could tell you more.

There is an older article about JPA and Scala, but I think it's outdated.

Landei
I already asked in the Scala mailing list ;) But maybe it would have been better to express my problem in a more "generic" way. Got no better (and only one) answer than here. And yes, the article is kind of antiquated. Anyway, thanks for your thoughts.
ifischer