scala hibernate/jpa - игнорировать автоматически сгенерированное растровое изображение $init$0 mapping
Попытка использовать Hibernate/ JPA с Scala. Встреча с интересной проблемой.
Это мое определение сущности.
@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 игнорировать это? Или как-то убрать его из отображения спящего режима? Или, может быть, что-то еще..
2 ответа
Я не знаю, откуда берется это автоматически сгенерированное поле, но вы можете попытаться упростить ваш класс, чтобы иметь меньше полей:
@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
}
Нашел пару интересных вещей по этому вопросу.
у меня есть это 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, что-то похожее на то, что описано здесь. Но я действительно не думаю, что это действительно достойно!