2

在尝试了不同的建议解决方案后,我还没有设法弄清楚这一点。

我正在使用 hibernate 3.6 和 mysql 5.x 并尝试保留我的实体(我排除了 getter 和 setter):

@Entity
@Table(name = "brand_managers")
public class BrandManager implements Serializable {

    /** Serial version unique id */
    private static final long serialVersionUID = -7992146584570782015L;

    /*--- Members ---*/

    /** The unique, internal ID of the entity. */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    /**
     * The creation time of this user
     */
    @Temporal(TemporalType.DATE)
    @Column(name = "creation_time")
    protected Calendar creationTime;

    /**
     * The hashed password
     */
    @Column(name = "password")
    protected String password;

    @Column(name = "first_name")
    protected String firstName;

    @Column(name = "last_name")
    protected String lastName;

    @Column(name = "email")
    protected String eMail;

    @Column(name = "address1")
    protected String address1;

    @Column(name = "address2", nullable = true)
    protected String address2;

    @Column(name = "city")
    protected String city;

    @Column(name = "state")
    protected String state;

    @Column(name = "zip", nullable = true)
    protected String zip;

    @Column(name = "country")
    protected String country;

    @Column(name = "phone")
    protected String phone;

    @Column(name = "brand_id")
    protected int brandId;

    /*--- Constructors ---*/

    /**
     * default
     */
    public BrandManager() {
    setCreationTime(Calendar.getInstance());
    }

    /**
     * @param password
     *            The hashed user password
     * @param firstName
     *            The first name
     * @param lastName
     *            The last name
     * @param eMail
     *            User eMail
     * @param address1
     *            User address
     * @param address2
     *            Another user address
     * @param city
     *            City of residence
     * @param state
     *            User state
     * @param country
     *            Country of of residence
     * @param phone
     *            User phone number
     * @param The
     *            id of the brand, managed by this brand manager
     */
    public BrandManager(String password, String firstName, String lastName, String eMail, String address1, String address2, String city,
        String state, String zip, String country, String phone, int brandId) {
    this();
    this.password = password;
    this.firstName = firstName;
    this.lastName = lastName;
    this.eMail = eMail;
    this.address1 = address1;
    this.address2 = address2;
    this.city = city;
    this.state = state;
    this.zip = zip;
    this.country = country;
    this.phone = phone;
    this.brandId = brandId;
    }

    /*--- Overridden Methods ---*/

    /**
     * Equality is based on the e-mail of this brand manager
     */
    @Override
    public boolean equals(Object obj) {

    if ((obj == null) || !(obj instanceof BrandManager)) {
        return false;
    }

    // reference comparison
    if (obj == this) {
        return true;
    }

    final BrandManager other = (BrandManager) obj;

    return new EqualsBuilder().append(geteMail(), other.geteMail()).isEquals();
    }

    /**
     * The unique hash code based on the e-mail of this brand manager
     */
    @Override
    public int hashCode() {
    return new HashCodeBuilder().append(this.geteMail()).toHashCode();
    }

    /**
     * Returning first name, last name and email.
     */
    @Override
    public String toString() {
    return ("First name: " + getFirstName() + ", Last name: " + getLastName() + ", E-Mail: " + geteMail());
    }

我在我的数据库中创建了一个相应的表:

CREATE TABLE `brand_managers` (
  `id` bigint(20) NOT NULL,
  `creation_time` datetime NOT NULL,
  `password` varchar(45) NOT NULL,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  `email` varchar(45) NOT NULL,
  `address1` varchar(45) NOT NULL,
  `address2` varchar(45) DEFAULT NULL,
  `city` varchar(45) NOT NULL,
  `state` varchar(45) NOT NULL,
  `zip` varchar(45) DEFAULT NULL,
  `country` varchar(45) NOT NULL,
  `phone` varchar(45) NOT NULL,
  `brand_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`)

当试图持久化这个实体的一个新实例时,我得到:

2012-07-21 12:24:03 JDBCExceptionReporter [WARN] SQL Error: 1364, SQLState: HY000
2012-07-21 12:24:03 JDBCExceptionReporter [ERROR] Field 'id' doesn't have a default value
2012-07-21 12:24:03 HibernateTask [ERROR] Hibernate exception caught in me.comocomo.server.dao.objectModel.club.register.BrandManager - could not insert: [me.comocomo.server.dao.objectModel.club.register.BrandManager]
2012-07-21 12:24:03 AssertionFailure [ERROR] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in me.comocomo.server.dao.objectModel.club.register.BrandManager entry (don't flush the Session after an exception occurs)
    at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82)
    at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:190)
    at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:147)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)

现在,我已经设法通过使用自动增量来解决它,这意味着当我更改 id 列(即 PK)时,如下所示:

ALTER TABLE `MYDB`.`brand_managers` CHANGE COLUMN `id` `id` BIGINT(20) NOT NULL AUTO_INCREMENT  ;

它工作得很好!

我不介意以这种方式实际工作(使用自动递增的 id),但我根本不明白为什么这是唯一真正有效的星座。为什么我不能使用“IDENTITY”生成器生成长类型唯一 ID?

4

1 回答 1

5

这就是 IDENTITY 生成器:一个依赖于自动增量字段来生成唯一 ID 的生成器,并在保存记录后向数据库询问生成的 ID。

如果您希望在内存中生成 ID,您可以使用 UUID 生成器。

大多数生成器要求数据库生成 ID,因为它是架构中唯一可靠和共享的组件。如果你有几个应用程序,每个应用程序都将记录保存在同一个表中,并且每个应用程序都使用自己的生成器,那么显然会导致冲突。询问数据库解决了这个问题:每个应用程序都同意使用自增字段、序列或表,一切都很好。

于 2012-07-21T10:01:06.003 回答