Scala hibernate / jpa - ignore auto-generated bitmap $ init $ 0

Trying to use hibernate / jpa using scala. Running into an interesting issue.

This is the definition of my essence.

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

When I run a sleep request, I get the following exception:

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

Obviously, jpa by default creates a mapping for scala bitmap with auto-generated $ init $ 0. I do not know what makes scala generate it. But regardless of whether there is any solution to tell jpa to ignore it? Or somehow remove it from the sleep mode display? Or maybe something else.

+6
source share
2 answers

I don’t know where this auto-generated field comes from, but you can try to arrange your class to have fewer fields:

 @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 } 
0
source

Found a couple of interesting things about this problem.

I have this Model class in my application:

 @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 = _ 

}

This class is compiled into a java class called User , which in turn is defined as follows:

 @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 actually comes from a class upgrade, and I thought that the Ebean library that I am currently using was responsible. But after reading your post, I went to investigate whether the JPA is really doing some kind of bytecode improvement on this object. To test this, I created a copy project, but in Java. The generated code for the User class does not have a bitmap$init$0 field, as shown below:

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

All this problem led me to this post, and I certainly agree. JPA integration with Scala Ebean / Hibernate seems to be a real pain. I still do not understand if this bitmap$ini$0 field is added to the bytecode of the by Ebean class or something else.

It seems that you can try to get around this behavior by matching the annotation ( @Transitent ) with the generated Java bytecode, first compiling the code for java, then in Scala, something similar to what is described here . But I really do not think that it is really worthy!

0
source

Source: https://habr.com/ru/post/916703/


All Articles