使用视图作为 Hibernate 的连接表

Ben*_*Ben 5 java mysql hibernate view jakarta-ee

我有两个实体,我想通过一个公共字符串加入它们。我创建了一个我想用作连接表的视图。除了当我尝试删除一个实体时,这一切都很好。Hibernate 然后尝试从该视图中删除,这当然会失败。使用的数据库是 MySQL。

所以我有

@Entity
public class Event {

   ...
   String productId;
   Date eventDatetime;
   ...
}

@Entity
public class Stock {
   ...
   String productId;
   ...
}
Run Code Online (Sandbox Code Playgroud)

我在 MySQL 中创建了一个视图

DROP VIEW IF EXISTS EVENT_STOCK_VIEW;
create view EVENT_STOCK_VIEW AS
SELECT EVENT.EVENT_ID, STOCK.STOCK_ID 
FROM EVENT, STOCK 
where STOCK.PRODUCT_ID = EVENT.PRODUCT_ID;
Run Code Online (Sandbox Code Playgroud)

在事件中我添加了:

@ManyToOne(fetch=FetchType.LAZY)
@JoinTable(name="EVENT_STOCK_VIEW",
    joinColumns=@JoinColumn(name="EVENT_ID"),
    inverseJoinColumns=@JoinColumn(name="STOCK_ID",updatable=false,insertable=false))
public Stock getStock(){
    return this.stock;
}
Run Code Online (Sandbox Code Playgroud)

并有库存:

@OneToMany(fetch=FetchType.LAZY)
    @JoinTable(name="EVENT_STOCK_VIEW",
    joinColumns=@JoinColumn(name="STOCK_ID",updatable=false,insertable=false),       inverseJoinColumns=@JoinColumn(name="EVENT_ID",updatable=false,insertable=false))
    @OrderBy("eventDatetime DESC")
    public List<Event> getEvents(){
        return events;
}
Run Code Online (Sandbox Code Playgroud)

我用谷歌搜索了一下,找到了这个网站。但是解决方案并不是那么好(您必须在股票和事件之间使用实体)。

还有其他解决方案吗?

我可以使用休眠拦截器并覆盖 onPrepareStatement(String sql) 并检查 SQL 字符串是否包含来自 EVENT_STOCK_VIEW 的删除并返回一个虚拟命令。显然是我试图避免的黑客行为。

axt*_*avt 0

难道根本不用连接表就做不到吗?据我了解,您的关系实际上是只读的,因此以下方法应该可以正常工作:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "productId", 
    referencedColumnName = "productId", insertable = false, updateable = false)
public Stock getStock(){
    return this.stock;
}

...

@OneToMany(fetch=FetchType.LAZY, mappedBy = "stock")
@OrderBy("eventDatetime DESC") 
public List<Event> getEvents(){
    return events;
} 
Run Code Online (Sandbox Code Playgroud)