简体   繁体   English

JDBCExceptionReporter [ERROR]字段“ id”没有默认值

[英]JDBCExceptionReporter [ERROR] Field 'id' doesn't have a default value

After trying different suggested solutions I haven't managed to figure out this one. 在尝试了不同的建议解决方案后,我还没有弄清楚这一点。

I'm using hibernate 3.6 and mysql 5.x and trying to persist my entity (I excluded the getters & setters): 我正在使用hibernate 3.6和mysql 5.x,并尝试保留我的实体(我排除了getters和setters):

@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());
    }

I created a corresponding table in my DB: 我在数据库中创建了一个对应的表:

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`)

When trying to persist a new instance of this entity I get: 尝试保留该实体的新实例时,我得到:

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)

Now, I have managed to resolve it by using auto-increment, Meaning that when I altered the id column (which is the PK) as follows: 现在,我设法通过使用自动增量来解决它,这意味着当我如下更改id列(即PK)时:

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

It worked just fine! 一切正常!

I don't mind actually working this way (using auto-incremented id) but I simply don't understand why this is the only constellation that actually works. 我不介意以这种方式工作(使用自动递增的id),但是我根本不明白为什么这是唯一实际起作用的星座。 Why can't I generate a long type unique id using the "IDENTITY" generator? 为什么不能使用“ IDENTITY”生成器生成长类型的唯一ID?

That's what an IDENTITY generator is: a generator that relies on an auto-increment field to generate the unique ID, and asks the database for the generated ID once the record has been saved. 这就是IDENTITY生成器的含义:生成器依靠自动递增字段生成唯一ID,并在记录保存后向数据库询问生成的ID。

If you want the ID to be generated in memory you could use a UUID generator. 如果希望在内存中生成ID,则可以使用UUID生成器。

Most of the generators ask the database to generate the ID, because it's the only component in the architecture that is reliable and shared. 大多数生成器要求数据库生成ID,因为它是体系结构中唯一可靠且共享的组件。 If you have several applications each saving records in the same table, and each using their own generator, it will obviously lead to conflicts. 如果您有多个应用程序,每个应用程序将记录保存在同一张表中,并且每个记录使用自己的生成器,则显然会导致冲突。 Asking the database solves this problem: every application agrees to use an auto-increment field, or a sequence, or a table, and everything is fine. 询问数据库解决了这个问题:每个应用程序都同意使用自动递增字段,序列或表,一切都很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM