我使用在Postgres 4数据库上运行的Hibernate 4.3.10.Final(使用SpringData JPA)并遇到了一个非常奇怪的错误。我们的应用程序使用默认" public"之外的数据库。架构,当我们尝试插入数据时,Hibernate会删除正确的架构。
我们的模型由一个抽象的" Log"使用单类继承的类允许许多不同的对象类型插入关联的日志消息。见下面的代码。
模式已经存在(hibernate没有创建它)并且启动验证运行正常,但是当尝试插入新记录时,我们得到错误关系" booking_log"不存在 - 缺少架构修饰符(比如说 customapp )。请参阅下面日志中的第一行,以了解其他插入语句的外观。
我已经在映射阶段进行了挖掘并验证了Hibernate确实从@JoinTable注释中获取了架构,但不确定我们是如何丢失它的。
任何帮助调试或可能的解决方案都将不胜感激。
谢谢!
日志 - 抽象超类
@MappedSuperclass
@Table(name="log", schema=Constants.DB_SCHEMA)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="log_type_id", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Log {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="log_seq_gen")
@SequenceGenerator(allocationSize = 1, name="log_seq_gen", sequenceName=Constants.DB_SCHEMA + ".log_id_seq")
private Long id;
// ...
}
BookingLog
@Entity
@DiscriminatorValue("2")
public class BookingLog extends Log implements TenantResource<Company,Long> {
@JoinTable(name="booking_log",
schema = Constants.DB_SCHEMA,
joinColumns = { @JoinColumn(name="log_id", referencedColumnName="id", nullable=false, updatable=false)},
inverseJoinColumns = { @JoinColumn(name="booking_id", referencedColumnName="id", nullable=false, updatable=false)})
@ManyToOne(cascade=CascadeType.ALL)
private Booking booking;
///...
}
**记录**
2015-07-20_18:14:09.055 DEBUG org.hibernate.SQL - insert into customapp.booking_product (created_dt, created_by, modified_dt, modified_by, include_in_payroll, include_in_revenue, booking_id, description, payroll_percent, price, product_id, qty, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2015-07-20_18:14:09.072 DEBUG org.hibernate.SQL - insert into booking_log (log_date, details, log_time, user_id, booking_id, id) values (?, ?, ?, ?, ?, ?)
2015-07-20_18:14:09.176 DEBUG o.h.e.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
org.postgresql.util.PSQLException: ERROR: relation "booking_log" does not exist
答案 0 :(得分:0)
基于你的@JoinTable配置和hibernate生成的插入语句看起来问题就是你要将额外的字段/数据添加到booking_log表中的方式。
我需要更多有关您的模型的详细信息,但我认为您正在使用连接表而不是创建一个模拟连接表的类。
我的意思是,你有这个
BookingLog (*) --------------------------------------> (1) Booking
但我认为你真的需要这个
BookingLog (1) ---> (1) BookingLogAssociation (*) ---> (1) Booking
然后映射就像这样,
@Entity
@DiscriminatorValue("2")
public class BookingLog extends Log implements TenantResource<Company,Long> {
@OneToOne(mappedBy="bookingLog")
private BookingLogAssociation booking;
}
请注意 BookingLogAssociation
的属性,它们是您要在booking_log表中添加的额外字段/数据。
@Entity
@Table(name="booking_log")
@IdClass(BookingLogAssociationId.class)
public class BookingLogAssociation {
@Id
private long log_id;
@Id
private long booking_id;
@OneToOne
@PrimaryKeyJoinColumn(name="log_id", referencedColumnName="id")
private BookingLog bookingLog;
@ManyToOne
@PrimaryKeyJoinColumn(name="booking_id", referencedColumnName="id")
private Booking booking;
@Column(name="log_date")
@Temporal(TemporalType.DATE)
private Calendar logDate;
@Column(name="log_time")
@Temporal(TemporalType.TIME)
private Calendar logTime;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
// Could be just an attribute too
//@Column(name="user_id")
//private long userId;
...
}
代表BookingLogAssociation复合键的 BookingLogAssociationId
类。
public class BookingLogAssociationId implements Serializable {
private long log_id;
private long booking_id;
public int hashCode() {
return (int)(log_id + booking_id);
}
public boolean equals(Object object) {
if (object instanceof BookingLogAssociationId) {
BookingLogAssociationId otherId = (BookingLogAssociationId) object;
return (otherId.log_id == this.log_id) && (otherId.booking_id == this.booking_id);
}
return false;
}
您可以阅读有关此选项的更多信息here