如何创建支持通用ID(包括自动生成的ID)的通用实体模型类?

我有三个 种类的 对表的主键:

  • INT自动生成的主键,使用AUTO_INCREMENT数据库供应商(MySQL)的容量
  • CHAR(X) 主键,用于将用户可读的值存储为键(其中X是数字,并且50 <= X <= 60)
  • 复杂的主键,由表的2或3个字段组成。

另外,可能存在(或不存在)一些字段:

  • 版本,INT字段。
  • createdBy VARCHAR(60)字段和lastUpdatedBy VARCHAR(60)字段(还有更多字段,但这些涵盖了基本示例)。

以上示例:

  • 表格1

    • id int主键auto_increment
    • 版本int
    • 值char(10)
    • 由varchar(60)创建
    • lastUpdatedBy varchar(60)

  • 表2

    • id char(60)主键
    • shortDescription varchar(20)
    • longDescription varchar(100)

  • 表3

    • field1 int主键
    • field2 int主键
    • 十进制数(10,5)
    • 版本int

考虑到所有这些,我需要创建一组通用类来支持这些要求,并允许使用Hibernate 4.3和JPA 2.1进行CRUD操作。

这是我当前的模型(避免使用getter / setter来缩短代码示例):

@MappedSuperclass

public abstract class BaseEntity<T> implements Serializable {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

protected T id;

}

@MappedSuperclass

public abstract class VersionedEntity<T> extends BaseEntity<T> {

@Version

protected int version;

}

@MappedSuperclass

public abstract class MaintainedEntity<T> extends VersionedEntity<T> {

@Column

protected String createdBy;

@Column

protected String lastUpdatedBy;

}

@Entity

public class Table1 extends MaintainedEntity<Long> {

@Column

private String value;

}

@Entity

public class Table2 extends BaseEntity<String> {

@Column

private String shortDescription;

@Column

private String longDescription;

}

我目前正在测试保存的实例Table1Table2。我有以下代码:

SessionFactory sf = HibernateUtils.getSessionFactory();

Session session = sf.getCurrentSession();

session.beginTransaction();

Table1 newTable1 = new Table1();

newTable1.setValue("foo");

session.save(newTable1); //works

Table2 newTable2 = new Table2();

//here I want to set the ID manually

newTable2.setId("foo_id");

newTable2.setShortDescription("short desc");

newTable2.setLongDescription("long description");

session.save(newTable2); //fails

session.getTransaction().commit();

sf.close();

尝试保存时失败,Table2并且出现以下错误:

Caused by: java.sql.SQLException: Field 'id' doesn't have a default value

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)

该错误消息很明显,因为CHAR(X)字段没有默认值,并且也没有默认值(AFAIK)。我尝试将生成策略更改为,GenerationType.AUTO并得到了相同的错误消息。

我如何重塑这些类以支持这些要求?甚至更好的是,我如何提供一种取决于我所保存实体的密钥的生成策略,该策略可以由我自动生成或提供?

涉及的技术:

  • Java SDK 8
  • hibernate4.3.6
  • JPA 2.1
  • MySQL和Postgres数据库
  • 操作系统:Windows 7 Professional

注意:为了可以得到JPA 2.1的其他实现(如EclipseLink)的支持,以上内容可能会(可能会)更改。

回答:

您可以“强制解决”此强制派生类以实现方法,该方法将确保分配ID并使用@PrePersist对该方法进行注释。您可以为将为其自动生成ID的类提供默认实现。

Somethig喜欢:

@MappedSuperclass

public abstract class BaseEntity<T> implements Serializable {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

protected T id;

@PrePersist

public void ensureIdAssigned() {

ensureIdAssignedInternal();

}

public abstract void ensureIdAssignedInternal();

}

@MappedSuperclass

public abstract class AutoIdMaintaintedEntity<T> extends MaintainedEntity<T> { // provide default implementation for Entities with Id generated by @GeneratedValue(strategy=GenerationType.IDENTITY) on BaseEntity superclass

public void ensureIdAssignedInternal() {

// nothing here since the Id will be automatically assigned

}

}

@Entity

public class Table1 extends AutoIdMaintaintedEntity<Long> {

@Column

private String value;

}

@Entity

public class Table2 extends BaseEntity<String> {

@Column

private String shortDescription;

@Column

private String longDescription;

public void ensureIdAssignedInternal() {

this.id = generateMyTextId();

}

private String generateMyTextId() {

return "text id";

}

}

以上是 如何创建支持通用ID(包括自动生成的ID)的通用实体模型类? 的全部内容, 来源链接: utcz.com/qa/403230.html

回到顶部