当目标是复合键

时间:2016-04-11 19:04:46

标签: java hibernate jpa composite-key

当该关联的对象是复合键时,Hibernate似乎没有更新FK引用。

事务成功(没有错误,没有堆栈跟踪),但没有生成更新语句(我启用了hibernate日志记录)。

我尝试了各种级联注释(没有级联,ALL,PERSIST,甚至是SAVE_UPDATE)而没有任何症状变化。这种无更新的症状既存在于在线OpenXava屏幕,也存在于自定义Java代码中(在OpenXava操作中)。

应用程序数据库要求允许外部上传到表,因此我被告知切换到系统分配的密钥不是他们愿意追求的选项。

拥有关联(目前没有任何级联设置):

  @ManyToOne(fetch=FetchType.LAZY,optional=false)
  @Required
  @JoinColumns({
    @JoinColumn(name="programID",referencedColumnName="programID",nullable=false,unique=false,insertable=false,updatable=false),
    @JoinColumn(name="projectID",referencedColumnName="projectID",nullable=false,unique=false,insertable=false,updatable=false)
  })
  @DescriptionsList(descriptionProperties="parentProgram.programName,projectName")
  @ReferenceView("reference")
  private Project associatedProject;

反向关联:

  @OneToMany(mappedBy="associatedProject",fetch=FetchType.LAZY) //No cascade allowed
  @ReadOnly
  private Set<Asset> assets = new HashSet<Asset>();

有没有人知道这是否有一个开放的Hibernate错误?我找不到任何使用谷歌搜索,但也许有人有第一手经验。

谢谢, 罗伊。

编辑:作为解决方法,我尝试编写自己的HQL更新。

update Asset set associatedProject = :ap where assetKey = :key

在处理SET子句时,对于一个迟钝的Hibernate语法错误unexpected AST node: AND失败了。

update Asset set associatedProject.projectId = :projId, associatedProject.parentProgram = :pgm where assetKey = :key

生成update Asset cross join set projectID=?, programID=? where assetKey=?,然后在&#34;#&#34;

上无效语法失败

但是,我自己的SQL更新可以正常工作。

有没有人有更好的解决方法?或者对根问题有任何进一步的想法?

在我看来,这仍然指向一个Hibernate错误(当然它是一个错误 - 你只能跳过更新,没有任何错误或消息)复合关键处理。

2 个答案:

答案 0 :(得分:0)

Hibernate没有保存关系,因为你说它没有保存它。只需从你的两个@JoinColumn中删除insertable = false,updatable = false。

答案 1 :(得分:0)

以下是如何使用“派生身份”映射主键的开始,这可能会有所帮助。我只是猜你的模特。但这是一个开始......

@Entity
public class Program {
    @Id
    int id;

    @OneToMany(mappedBy="program")
    Set<Project> projects;

    ...
}

@Embeddable
public class ProjectID {
    int projectID;
    int programID; // corresponds to the type of Program's primary key

    ...
}

@Entity
public class Project {
    @EmbeddedId
    ProjectID id;

    @MapsId("programID") // maps 'programID' attribute of embedded ID
    @ManyToOne
    Program program;

    @OneToMany(mappedBy="associatedProject", fetch=FetchType.LAZY)
    Set<Asset> assets;

    ...
}

@Embeddable
public class AssetID {
    int assetID;
    ProjectID projectID; // corresponds to the type of Project's primary key

    ...
}

@Entity
public class Asset {
    @EmbeddedId
    AssetID id;

    @MapsId("projectID") // maps 'projectID' attribute of embedded ID
    @ManyToOne(fetch=FetchType.LAZY, optional=false)
    Project associatedProject;

    ...
}

衍生身份在JPA 2.1规范第2.4.1节中讨论。