我想使用Hibernate在Postgres 9上执行CRUD操作。
实体:
@Entity
@Table(name = "MESSAGE_HISTORY_RECORD")
public class MessageHistoryRecord {
@EmbeddedId
private MessageCompoundKey compoundKey;
@Column
private String responseChannel;
@ElementCollection
private List<Trace> traces;
@Column
private byte[] payload;
//getters and setters
}
复合ID实体:
@Embeddable
public class MessageCompoundKey implements Serializable {
private static final long serialVersionUID = 9084329307727034214L;
@Column
private String correlatedMsgId;
@Column
private String messageId;
@Column
private String endpointId;
//getters and setters
}
ElementCollection实体:
@Embeddable
public class Trace implements Serializable{
private static final long serialVersionUID = 9084329307727034214L;
private Long timestamp;
private String description;
//getters and setters
}
我正在使用hibernate.hbm2ddl.auto=update
为我创建架构。
它为我创建了表格:
CREATE TABLE "public"."message_history_record"
(
correlatedmsgid varchar(255) NOT NULL,
endpointid varchar(255) NOT NULL,
messageid varchar(255) NOT NULL,
payload bytea,
responsechannel varchar(255),
CONSTRAINT message_history_record_pkey PRIMARY KEY (correlatedmsgid,endpointid,messageid)
)
;
CREATE UNIQUE INDEX message_history_record_pkey ON "public"."message_history_record"
(
correlatedmsgid,
endpointid,
messageid
)
;
CREATE TABLE "public"."messagehistoryrecord_traces"
(
messagehistoryrecord_correlatedmsgid varchar(255) NOT NULL,
messagehistoryrecord_endpointid varchar(255) NOT NULL,
messagehistoryrecord_messageid varchar(255) NOT NULL,
description varchar(255),
timestamp bigint
)
在保留任何对象时,我在messagehistoryrecord_traces
表中找不到任何条目。
Hibernate属性:
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=jdbc:postgresql://192.xx.xx.xx:5432/testdb
hibernate.connection.username=***
hibernate.connection.password=****
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.connection.pool_size=10
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
坚持sql:
Hibernate:插入MESSAGE_HISTORY_RECORD(payload,responseChannel,correlationMsgId,endpointId,messageId)值(?,?,?,?,?)
答案 0 :(得分:1)
根据您的配置,默认值应该适用于集合表的表名,列名和连接列名。这些默认值的构造如下:
表名称:引用实体的名称,附加下划线以及包含元素集合的实体属性的名称(MessageHistoryRecord_traces
)
加入列:附加引用实体的名称 带有下划线和实体表的主键列的名称。
仅当您在父实体中有一个主键字段时才允许第二种情况,在您的情况下不是这种情况。所以你自己指定了连接列,如下所示(我重命名了集合表名和外键列名,因为它们对我的数据库系统来说太长了):
@ElementCollection
@CollectionTable(name = "mhr_traces",
joinColumns={@JoinColumn(name="mhr_correlatedmsgid", referencedColumnName="correlatedmsgid"),
@JoinColumn(name="mhr_endpointid", referencedColumnName="endpointid"),
@JoinColumn(name = "mhr_messageid", referencedColumnName = "messageid")})
private List<Trace> traces = new ArrayList<>();
还有一件事:如果你还没有完成主要密钥类的equals()
和hashCode()
方法(你的帖子中看不到它们),你必须实现CONSTRAINT mrFK FOREIGN KEY (mhr_correlatedmsgid, mhr_endpointid, mhr_messageid) REFERENCES MESSAGE_HISTORY_RECORD (correlatedmsgid,endpointid,messageid)
和org.springframework.http.MediaType.getCharset()
方法。
您的表创建脚本也缺少外键definitino(如果它们不是自动生成的话,请手动添加它们):
getStringArray
根据您的数据库语法调整它(我不知道PostgreSQL)
通过这些调整,一切都适合我;确实在Oracle数据库系统和EclipseLink上作为持久性提供程序。我认为这不是特定于实现的
答案 1 :(得分:1)
您是否在跟踪列表中添加了任何内容,或者它是空的? 这对我的postgresql没有任何调整。随着hbm2ddl.auto设置为更新,hibernate也创建了表和它们之间的外键关系。以下是我使用的示例代码:
public class App
{
public static void main( String[] args )
{
System.out.println("Maven + Hibernate + Postgresql");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
MessageCompoundKey cKey = new MessageCompoundKey();
cKey.setCorrelatedMsgId("correlatedMsgId_2");
cKey.setEndpointId("endpointId_2");
cKey.setMessageId("messageId_2");
MessageHistoryRecord record = new MessageHistoryRecord();
record.setResponseChannel("ArsenalFanTv");
List<Trace> traces = new ArrayList<>();
Trace t1 = new Trace();
t1.setDescription("description_1");
t1.setTimestamp(System.currentTimeMillis());
traces.add(t1);
Trace t2 = new Trace();
t2.setDescription("description_2");
t2.setTimestamp(System.currentTimeMillis());
traces.add(t2);
record.setCompoundKey(cKey);
record.setTraces(traces);
session.save(record);
session.getTransaction().commit();
}
}
和我的配置文件(hibernate.cfg.xml)如下:
<hibernate-configuration>
<session-factory>
<!-- <property name="hibernate.bytecode.use_reflection_optimizer">false</property> -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.password">****</property>
<property name="hibernate.connection.url">jdbc:postgresql://127.0.0.1:5432/testdb</property>
<property name="hibernate.connection.username">****</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="com.skm.schema.MessageHistoryRecord"></mapping>
</session-factory>
</hibernate-configuration>
答案 2 :(得分:0)
我使用的是 StatelessSession而不是会话。根据文件:
无状态会话不实现第一级缓存,也不与任何二级缓存交互,也不实现事务性后写或自动脏检查,也不会对关联实例进行级联操作。 无状态会话会忽略收藏集。通过无状态会话执行的操作绕过Hibernate的事件模型和拦截器。由于缺少第一级缓存,无状态会话容易受到数据别名影响。
可在此thread上找到更多详情。
使用Session而不是StatelessSession后,它起作用了。