【发布时间】:2023-03-15 20:36:01
【问题描述】:
在 Wildfly 9 上使用 Hibernate 的 JPA。
我有 2 个实体是 ManyToMany
@Entity
@Table(name = "ASSET_GROUPS")
@XmlRootElement
@NamedQueries({ @NamedQuery(name = "AssetGroup.findAll", query = "SELECT a FROM AssetGroup a"),
@NamedQuery(name = "AssetGroup.findById", query = "SELECT a FROM AssetGroup a WHERE a.id = :id"),
@NamedQuery(name = "AssetGroup.findByName", query = "SELECT a FROM AssetGroup a WHERE a.name = :name") })
public class AssetGroup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "asset_groups_id_seq_gen", sequenceName = "asset_groups_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "asset_groups_id_seq_gen")
@Column(name = "ID", updatable = false)
private Long id;
@Size(max = 255)
private String name;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
name="ASSETS_ASSET_GROUPS",
joinColumns=@JoinColumn(name="ASSET_GROUP_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="ASSET_ID", referencedColumnName="ID"))
private List<Asset> assets;
...
第二个实体:
@Entity
@Table(name = "ASSETS")
@XmlRootElement
@NamedQueries({ @NamedQuery(name = "Asset.findAll", query = "SELECT a FROM Asset a"),
@NamedQuery(name = "Asset.findById", query = "SELECT a FROM Asset a WHERE a.id = :id"),
@NamedQuery(name = "Asset.findByName", query = "SELECT a FROM Asset a WHERE a.name = :name")
})
public class Asset implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "assets_id_seq_gen", sequenceName = "assets_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "assets_id_seq_gen")
@Column(name = "ID", updatable = false)
private Long id;
@Size(max = 255)
private String name;
@ManyToMany(fetch=FetchType.EAGER, mappedBy="assets")
List<AssetGroup> assetGroups;
public Asset() {
}
...
我可以通过 REST 服务毫无问题地添加这些东西,但是这段代码给了我一个错误:
@POST
@Override
@Consumes({"application/xml", "application/json"})
@Transactional
public void create(Asset entity) {
L.info("Creating {}", entity);
AssetGroup g = groupService.findAll().get(0);
L.info("Adding to asset group {}", g);
super.create(entity);
L.info("Created Asset {}", entity.getId());
g.addAsset(entity); // <---- Works if this is commented out but does not create relationship!
L.info("Created");
}
这是上述函数的输出:
11:05:29,667 信息 [auth.entities.service.AssetGroupsFacadeREST] (默认任务2)创建entities.AssetGroup@bbad39d
11:05:29,672 INFO [auth.entities.service.AssetGroupsFacadeREST](默认任务 2)已创建
11:05:29,703 信息 [auth.entities.service.AssetsFacadeREST] (默认任务3)创建entities.Asset@1be5f67a
11:05:29,728 INFO [auth.entities.service.AssetsFacadeREST] default task-3) 添加到资产组entities.AssetGroup@323e7d95
11:05:29,728 INFO [auth.entities.service.AssetsFacadeREST](默认任务 3)创建资产 1
11:05:29,728 INFO [auth.entities.service.AssetsFacadeREST](默认任务 3)已创建
11:05:29,730 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务 3)SQL 错误:0,SQLState:23503
11:05:29,730 错误 [org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务 3) 错误:在表“asset_asset_groups”上插入或更新违反了外键约束“fk_6bl48uhb94hsmq6knndfiq3y”详细信息:表“assets”中不存在键 (asset_id)=(1)。
很明显,由于资产 id 1 被持久化,数据库失败了,那么我该如何解决这个问题?我曾尝试在实体管理器上执行 commit(),但它不起作用。我尝试使用需要新事务的 @Transactional 注释来注释 super.create(entity) 方法,但没有任何效果。
请注意,如果我注释掉注释行,实体会被保存,但不会在链接表中创建关系。
【问题讨论】: