9

我的目标是创建一个具有唯一字段 IMEI 的实体设备,我想将其用作主键,并在设备注册时指定它(在创建实体时手动指定)。我使用 Spring roo 工具进行开发,并使用休眠作为 ORM。

当我在实体声明中指定时:

@RooJavaBean
@RooToString
@RooJpaActiveRecord(identifierField = "IMEI", identifierType = String.class)
public class Device {...}

我得到这个生成:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "IMEI")
private String Device.IMEI;

在使用 mysql db 将项目部署到服务器时,出现此错误:

2013-03-17 20:03:23,136 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - HHH000389: Unsuccessful: create table device (imei varchar(255) not null auto_increment, model varchar(255), name varchar(255) not null, version integer, primary key (imei))
2013-03-17 20:03:23,136 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - Incorrect column specifier for column 'imei'

然后我覆盖 roo 生成的字段

@Id
@GeneratedValue(generator = "org.hibernate.id.Assigned")
@Column(name = "the_code")
private String code;

(我在这里找到了这个)

但仍然得到错误。然后我将代码简单地更改为:

 @Id
private String IMEI;

然后它工作正常并要求我在保存实体之前指定imei字段。

我的问题是:

使用我的自定义字段作为 id 是否正确?

通过String可以吗?

它不是用hibernate生成而是从设备imei中获取的可以吗?

什么是 org.hibernate.id.Assigned?

为什么 roo 为 @RooJpaActiveRecord(identifierField = "IMEI", identifierType = String.class) 生成的代码不起作用?

是否可以创建字符串自动生成的主键?

什么是默认 GeneratedValue 策略值(我的最后一个案例)?

我已经阅读了官方文档,但没有完全理解,请参考我可以阅读所有这些的文章。

谢谢,对不起,很长的问题。

4

3 回答 3

21

一个简单的解决方案可能是@PrePersist在您的实体类上使用注释。

只需添加方法

@PrePersist
private void ensureId(){
    this.setId(UUID.randomUUID().toString());
}

并摆脱@GeneratedValue注释。

PrePersist 文档:http ://docs.oracle.com/javaee/5/api/javax/persistence/PrePersist.html

斯特凡诺

于 2013-03-18T15:53:02.457 回答
16

@GeneratedValue(strategy = GenerationType.AUTO)不能与String类型一起使用。因此,如果您想String用作 ID,则必须手动分配它。但如果适合您的需要,可以使用 String 作为 ID。

使用org.hibernate.id.Assigned还意味着您必须在保存数据之前分配 ID 值。

未添加注释时@GeneratedValue,默认分配生成器,这意味着标识符的值必须由应用程序设置。

有关详细信息,请参阅hibernate 手册

于 2013-03-18T05:26:18.120 回答
4

目前,这可能是不必要的。但我认为我们应该为某人更新这张票。

我是回答堆栈溢出的新手,所以希望这是有道理的

如果要在休眠中自动生成字符串作为 ID,可以使用IdentifierGenerator和 @GenericGenerator 定义规则。

实体声明:

public class Device {...

    @Id
    @GenericGenerator(name = "sequence_imei_id", strategy = "com.supportmycode.model.ImeiIdGenerator")
    @GeneratedValue(generator = "sequence_imei_id")
    @Column(name = "IMEI")
    private String IMEI;

...}

义美发电机声明:

public class ImeiIdGenerator implements IdentifierGenerator {...
    public Serializable generate(SessionImplementor session, Object object) throws HibernateException {

            // define your IMEI, example IMEI1, IMEI2,...;
            return "IMEI"+ UUID.randomUUID().toString();
...}

当您保存设备对象时,IMEI(id) 将由 ImeiIdGenerator 自动生成。

于 2018-05-07T09:52:42.433 回答