Play Ebean 从 2.4 升级到 2.5 后不生成 Id

Posted

技术标签:

【中文标题】Play Ebean 从 2.4 升级到 2.5 后不生成 Id【英文标题】:Play Ebean does not generate Id after upgrading from 2.4 to 2.5 【发布时间】:2017-11-20 04:19:10 【问题描述】:

我目前正在将我的应用程序的播放从 2.4.x 升级到 2.5.18。根据 play 的文档,我还将 play-ebean 从 1.0.0 升级到 3.2.0,它使用 ebean 10.4.x。升级后,每当我将 bean 插入 h2 数据库时,都会出现此错误:

[DataIntegrityException: Error[NULL not allowed for column "ID"; SQL statement: insert into users (email, name, first_name, last_name, last_login, active, email_validated) values (?,?,?,?,?,?,?) [23502-185]]]

似乎 ebean 没有为新插入的 bean 生成 id。在保存之前手动设置 id 不会遇到错误(user.id = 123)。但是,我真的希望 id 生成再次起作用。

版本:

玩 2.5.18 play-ebean 3.2.0 h2 数据库 1.4.185 死锁 2.5.6 java 1.8.0 更新151

在 plugins.sbt 中

addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.2.0")

在 build.sbt 中

lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean).settings(libraryDependencies ++= appDependencies)

libraryDependencies ++= Seq(
  javaCore,
  javaJdbc,
  cache,
  evolutions,
  javaWs
)

在 application.conf 中

ebean.default = ["models.*"]

这是一个存储用户信息的模型。它还实现了 deadbolt 的 Subject。我四重检查了我没有覆盖模型中的保存。

package models;
...
@Entity
@Table(name = "users")
public class User extends AppModel implements Subject 
    private static final long serialVersionUID = 1L;
    @Id
    public Long id;

    @Constraints.Email
    public String email;

    public String name;

    public String firstName;

    public String lastName;

    @Formats.DateTime(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date lastLogin;

    public boolean active;

    public boolean emailValidated;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    public List<Mapping> mappings;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    public List<DbConn> dbconns;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    public List<OntoFile> ontofiles;

    @ManyToMany
    public List<SecurityRole> roles;

    @OneToMany(cascade = CascadeType.ALL)
    public List<LinkedAccount> linkedAccounts;

    @ManyToMany
    public List<UserPermission> permissions;

    public static final Finder<Long, User> find = new Finder<Long, User>(User.class);

    ...

    public static User create(final AuthUser authUser) 
        final User user = new User();
        user.roles = Collections.singletonList(SecurityRole
                .findByRoleName(controllers.Application.USER_ROLE));
        user.active = true;
        user.lastLogin = new Date();
        user.linkedAccounts = Collections.singletonList(LinkedAccount
                .create(authUser));

        if (authUser instanceof EmailIdentity) 
            final EmailIdentity identity = (EmailIdentity) authUser;
            user.email = identity.getEmail();
            user.emailValidated = false;
        

        if (authUser instanceof NameIdentity) 
            final NameIdentity identity = (NameIdentity) authUser;
            final String name = identity.getName();
            if (name != null) 
                user.name = name;
            
        

        if (authUser instanceof FirstLastNameIdentity) 
          final FirstLastNameIdentity identity = (FirstLastNameIdentity) authUser;
          final String firstName = identity.getFirstName();
          final String lastName = identity.getLastName();
          if (firstName != null) 
            user.firstName = firstName;
          
          if (lastName != null) 
            user.lastName = lastName;
          
        

        user.save(); // error happens here
        Ebean.save(user); // this does not work either
        return user;
    
    ...

我不知道为什么会这样,但是以前写这个应用程序的人把它放在那里,它从来没有引起任何问题,所以我现在把它放在那里。此外,将 User 扩展到 Model 而不是 AppModel 并不能修复错误。

package models;

import javax.persistence.MappedSuperclass;
import io.ebean.Model;

@MappedSuperclass
public class AppModel extends Model

我也尝试过配置 ebean 服务器。 id 生成器和包都是空的。我将模型添加到列表中,但仍然出现错误。这是否意味着 ebean 配置不正确?

package models;
...
public class MyServerConfigStartup implements ServerConfigStartup 
    public void onStart(ServerConfig serverConfig) 
        List<IdGenerator> gen = serverConfig.getIdGenerators();
        System.out.println(gen); // []

        List<String> pack1 = serverConfig.getPackages();
        System.out.println(pack1); // []
        ArrayList<String> packages = new ArrayList<String>();
        packages.add("models.*");
        serverConfig.setPackages(packages);
        List<String> pack2 = serverConfig.getPackages();
        System.out.println(pack2); // [models.*]
    

感谢任何帮助。谢谢。

【问题讨论】:

【参考方案1】:

事实证明,h2 数据库中的 id 列现在需要具有 auto_increment。在所有表上运行 ALTER TABLE name ALTER COLUMN colName bigint not null auto_increment 可以解决此问题。

【讨论】:

以上是关于Play Ebean 从 2.4 升级到 2.5 后不生成 Id的主要内容,如果未能解决你的问题,请参考以下文章

Play 2.4 / Ebean / JPA / hibernate-entitymanager 的正确配置是啥?

子项目 Play 2.4 中的 Ebean 增强

playframework 2.4 基本ebean配置

玩2.4 Ebean分页问题

从 Play Framework 更改 WS API! 2.4 至 2.5

升级 Play 到 2.4,Slick 到 3.1.1,值 withTransaction 不是 play.api.db.slick.Database 的成员