【问题标题】:How persist Map<String, Embeddable type> using hibernate in mySQL如何在 mySQL 中使用 hibernate 持久化 Map<String, Embeddable type>
【发布时间】:2016-11-29 11:21:16
【问题描述】:

我想使用 Hibernate(4.3.6 Final) 来持久化一个 Map,其中基本类型为键,非实体可嵌入复合类型值作为值。

我对基本类型作为键和值没有任何问题,我以相同的方式完成了所有操作,没关系。当我将 map 的值更改为可嵌入的复合类型时遇到问题,如下所示。

但我收到错误:

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: '字段列表'中的未知列'hash'

你能帮助我做错什么或错过什么吗?

准备好保存我的地图的表

image of table user_address

我的地图在实体 USER(片段)中持久化

@ElementCollection
@CollectionTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID"))
@MapKeyColumn(name="ADDRESS_TYPE")
@AttributeOverrides({@AttributeOverride(name="addressLine1", column=@Column(name="USER_ADDRESS_LINE_1")),
        @AttributeOverride(name="addressLine2", column=@Column(name="USER_ADDRESS_LINE_2"))})
private Map<String,Address> address = new HashMap<String, Address>();

可嵌入复合类型ADDRESS(片段)

@Embeddable
public class Address {

@Column(name="ADDRESS_LINE_1")
private String addressLine1;

@Column(name="ADDRESS_LINE_2")
private String addressLine2;

@Column(name="CITY")
private String city;

@Column(name="STATE")
private String state;

@Column(name="ZIP_CODE")
private String zipCode;

public Address() {
}

主要方法 公共类应用程序{

public static void main(String[] args) {
    Session session = HibernateUtil.getSessionFactory().openSession();

    try {
        Transaction transaction = session.beginTransaction();


        User user = new User();

        Address address = new Address();
        Address address2 = new Address();
        setAddressFields(address);
        setAddressFields2(address2);
        user.getAddress().put("ONE",address);
        user.getAddress().put("TWO",address2);
        setUserFields(user);

        session.save(user);

        transaction.commit();

    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        session.close();
        HibernateUtil.getSessionFactory().close();
    }


}

private static void setUserFields(User user) {
    user.setAge(22);
    user.setBirthDate(new Date());
    user.setCreatedBy("kmb");
    user.setCreatedDate(new Date());
    user.setEmailAddress("kmb385");
    user.setFirstName("Kevin");
    user.setLastName("bowersox");
    user.setLastUpdatedBy("kevin");
    user.setLastUpdatedDate(new Date());
}

private static void setAddressFields(Address address) {
    address.setAddressLine1("Line 1");
    address.setAddressLine2("Line 2");
    address.setCity("New York");
    address.setState("NY");
    address.setZipCode("12345");
}

private static void setAddressFields2(Address address) {
    address.setAddressLine1("Line 3");
    address.setAddressLine2("Line 4");
    address.setCity("Corning");
    address.setState("NY");
    address.setZipCode("12345");
}

}

错误全文:

DEBUG - 插入 USER_ADDRESS (USER_ID, hash, value, ADDRESS_LINE_1, ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值(?, ?, ?, ?, ?, ?, ?, ?) Hibernate:插入 USER_ADDRESS (USER_ID, hash, value, ADDRESS_LINE_1, ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值 (?, ?, ?, ?, ?, ?, ?, ?) 调试 - 无法执行语句 [n/a] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:“字段列表”中的未知列“哈希” 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:423) 在 com.mysql.jdbc.Util.handleNewInstance(Util.java:404) 在 com.mysql.jdbc.Util.getInstance(Util.java:387) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:939) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814) 在 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) 在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) 在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) 在 com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) 在 org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) 在 org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1311) 在 org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:67) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349) 在 org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) 在 org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) 在 org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) 在 org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) 在 org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) 在 org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) 在 com.infinitekills.data.Application.main(Application.java:33) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 警告 - SQL 错误:1054,SQLState:42S22 错误 - “字段列表”中的未知列“哈希” 信息 - HHH000010:在批处理发布时,它仍然包含 JDBC 语句 调试 - HHH000420:关闭未发布的批次 调试 - 释放 JDBC 连接 调试 - 已发布 JDBC 连接 调试 - HHH000031:关闭 DEBUG - 在取消注册所有子 ServiceRegistries 时隐式销毁 ServiceRegistry org.hibernate.exception.SQLGrammarException:无法执行语句 在 org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80) 在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211) 在 org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) 在 org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1311) 在 org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:67) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349) 在 org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) 在 org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) 在 org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) 在 org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) 在 org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) 在 org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) 在 com.infinitekills.data.Application.main(Application.java:33) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:“字段列表”中的未知列“哈希” 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:423) 在 com.mysql.jdbc.Util.handleNewInstance(Util.java:404) 在 com.mysql.jdbc.Util.getInstance(Util.java:387) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:939) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814) 在 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) 在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) 在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) 在 com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ... 17 更多 信息 - HHH000030:清理连接池 [jdbc:mysql://localhost:3306/ifinances] DEBUG - 在取消注册所有子 ServiceRegistries 时隐式销毁引导注册表

最有趣的 IMO 错误监听片段

Hibernate 尝试使用带有哈希和值的 sql 插入,但我的表中当然没有这些列。

DEBUG - 插入 USER_ADDRESS (USER_ID, hash, value, ADDRESS_LINE_1, ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值(?, ?, ?, ?, ?, ?, ?, ?) Hibernate:插入 USER_ADDRESS (USER_ID, hash, value, ADDRESS_LINE_1, ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值(?, ?, ?, ?, ?, ?, ?, ?)

提前感谢您的建议

【问题讨论】:

    标签: java mysql hibernate


    【解决方案1】:

    我认为我部分找到了解决方案。

    @AttributeOverride 有问题,我不知道为什么,因为我使用完全相同的符号来持久化地址集合(可嵌入复合类型)

    我将非常感谢帮助,为什么在我使用 Map 时尝试覆盖列名时会出现问题,而当我尝试持久化相同可嵌入复合类型(地址)的集合时一切正常

    当我更改类地址以避免覆盖列名称时,我的地图已成功持久化。换句话说,我已将 Address 类型的列名更改为与 USER_ADDRESS 中的列名完全对应。

    改变复合嵌入类型

    现在列名与要持久化映射的表中的列名完全对应

    @Embeddable
    public class Address {
    
        @Column(name="USER_ADDRESS_LINE_1")
        private String addressLine1;
    
        @Column(name="USER_ADDRESS_LINE_2")
        private String addressLine2;
    
        @Column(name="CITY")
        private String city;
    
            @Column(name="STATE")
        private String state;
    
        @Column(name="ZIP_CODE")
        private String zipCode;
    
        public Address() {
        }
    ...
    

    映射在不覆盖的情况下持续存在

    @ElementCollection
    @CollectionTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID"))
    @MapKeyColumn(name="ADDRESS_TYPE")
    @Columns(columns = {
            @Column(name="USER_ADDRESS_LINE_1"),
            @Column(name="USER_ADDRESS_LINE_2"),
            @Column(name="CITY"),
            @Column(name="STATE"),
            @Column(name="ZIP_CODE")
    })
    private Map<String,Address> address = new HashMap<String, Address>();
    

    结果

    地图保存后从表 USER_ADDRESS 中选择

    休眠:插入 USER_ADDRESS(USER_ID、ADDRESS_TYPE、USER_ADDRESS_LINE_1、USER_ADDRESS_LINE_2、CITY、STATE、ZIP_CODE)值(?、?、?、?、?、?、?) DEBUG - 插入 USER_ADDRESS (USER_ID, ADDRESS_TYPE, USER_ADDRESS_LINE_1, USER_ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值(?, ?, ?, ?, ?, ?, ?) Hibernate:插入 USER_ADDRESS (USER_ID, ADDRESS_TYPE, USER_ADDRESS_LINE_1, USER_ADDRESS_LINE_2, CITY, STATE, ZIP_CODE) 值(?, ?, ?, ?, ?, ?, ?) 调试 - 完成插入集合:插入 2 行 DEBUG - 提交的 JDBC 连接 调试 - HHH000420:关闭未发布的批次 调试 - 释放 JDBC 连接 调试 - 已发布 JDBC 连接 调试 - HHH000031:关闭 调试 - 在取消注册所有子 ServiceRegistries 时隐式销毁 ServiceRegistry 信息 - HHH000030:清理连接池 [jdbc:mysql://localhost:3306/ifinances] DEBUG - 在取消注册所有子 ServiceRegistries 时隐式销毁引导注册表

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多