6

scala で hibernate/jpa を使用しようとしています。興味深い問題に直面しています。

これが私のエンティティ定義です。

@Entity
class Product(n: String, d: Double) extends EntityBase {

  def this() = this("", 0)
  def this(n: String) = this(n, 0)

  var name: String = n
  var price: Double = d

  @ManyToOne
  @JoinColumn(name="orderId")
  var order: Order = _

  override def toString = "Product: " + id + " " + name
}

休止状態のクエリを実行すると、次の例外が発生します。

[SQLGrammarException: ERROR: column this_.bitmap$init$0 does not exist Position: 29]

明らかに jpa は、デフォルトで scala 自動生成フィールド bitmap$init$0 のマッピングを作成します。scalaがそれを生成する原因がわかりません。しかし、無視するようにjpaに指示する解決策はありますか? または、どういうわけか休止状態のマッピングから削除しますか? それとも何か他のもの..

4

2 に答える 2

0

この問題について興味深いことがいくつか見つかりました。

私は自分のアプリケーションにこのModelクラスを持っています:

@Entity
@Table(name="users")
class User extends Model{
  @Id
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq")
  @Column(name="id", updatable=false, nullable=false)
  val id:Long = 0L

  @BeanProperty var name:String = _
  @BeanProperty var email:String = _ 

}

このクラスは という名前の Java クラスにコンパイルされ、User次のように定義されます。

@Entity
@Table(name="users")
@ScalaSignature(bytes=long array of bytes)
public class User extends Model
   implements ScalaObject, EntityBean
{

   @Id
   @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq")
   @Column(name="id", updatable=false, nullable=false)
   private final long id;
   private String name;
   private String email;
   private volatile int bitmap$init$0;
   private static String _EBEAN_MARKER = "models.User";

   ...

   public long id()
  {
    if ((_ebean_get_bitmap$init$0() & 0x1) != 0)
    {
        _ebean_get_id(); return _ebean_get_id(); 
   } 
   throw new 
         UninitializedFieldError("Uninitialized field: User.scala: 17".toString());
    }

   public String name()
   {
   if ((_ebean_get_bitmap$init$0() & 0x2) != 0)
   {
     _ebean_get_name(); return _ebean_get_name();
   } throw new 
           UninitializedFieldError("Uninitialized field: User.scala: 19".toString()); 
   } 

   public void name_$eq(String paramString) { 
     _ebean_set_name(paramString); 
      _ebean_set_bitmap$init$0(_ebean_get_bitmap$init$0() | 0x2);
   }

  ....

これは実際にはクラスの強化によるものであり、現在使用しているライブラリbitmap$init$0が原因であると考えていました。Ebeanしかし、あなたの投稿を読んだ後、JPA 自体がこのオブジェクトに対して何らかのバイトコード拡張を行っているかどうかを調査しました。これを確認するために、Java でコピー プロジェクトを作成しました。User次のように、生成されたクラスのコードにはたまたまbitmap$init$0フィールドがありません。

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="users")
public class User
{

  @Id
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="users_id_seq")
  @Column(name="id", updatable=false, nullable=false)
  private Long id;
  private String name;
  private String email;

 public void setId(Long id)
 {
    this.id = id;
 }

 public Long getId() {
   return this.id;
 }

public String getName() {
   return this.name;
 }
 public void setName(String name) {
   this.name = name;
 }
 public String getEmail() {
    return this.email;
 }
 public void setEmail(String email) {
    this.email = email;
  }
}

この種の問題はすべて私をこの投稿に導きました、そして私は間違いなく同意します. JPA を Scala Ebean/Hibernate に統合するのは本当に大変なことのようです。bitmap$ini$0このフィールドが Ebean によってクラスのバイトコードに注入されたのか、それとも何か他のものなのか、まだわかりませんでした。

@Transitent生成された Java バイトコードに注釈 ( ) を関連付けることで、この種の動作をバイパスしようとすることができるようです。最初にコードを Java 用にコンパイルし、次に Scala にコンパイルします。しかし、それは本当に価値があるとは思いません!

于 2012-11-11T00:34:46.027 に答える
0

自動生成されたフィールドがどこから来ているのかわかりませんが、クラスを合理化してフィールドを少なくすることができます:

@Entity
class Product(var name: String = "", var price: Double = 0) extends EntityBase {

  @ManyToOne
  @JoinColumn(name="orderId")
  var order: Order = _

  override def toString = "Product: " + id + " " + name
}
于 2012-06-03T02:48:33.107 に答える