Hibernate is not mapping object correctly ("Bad value for type" exception) when using compound primary keys in a junction table

huangapple go评论80阅读模式
英文:

Hibernate is not mapping object correctly ("Bad value for type" exception) when using compound primary keys in a junction table

问题

我注意到你遇到了一个问题,即在查询ConditionSetEvent时出现了类型错误,它似乎尝试将UUID放入整数字段中。问题可能出在你的JPA查询方法中。

在你的ConditionSetEvent实体中,你使用了复合主键 ConditionSetEventId,其中包含了 ConditionSetIdUUID。在你的JPA查询方法中,你尝试使用 cse.id.eventId 进行查询,这可能导致类型不匹配的错误,因为eventId是UUID类型。

你可以尝试修改查询方法,以匹配ConditionSetEventId的结构。以下是一个可能的修复:

@Query("select cse from ConditionSetEvent cse where cse.id.eventId = :eventId")
List<ConditionSetEvent> findByEventId(@Param("eventId") UUID eventId);

这里,我们使用 cse.id.eventId 来匹配 ConditionSetEventId 中的UUID字段。

请尝试这个修复,看看是否能够解决你的问题。如果问题仍然存在,可能需要进一步检查你的实体和数据库结构,确保它们之间的映射正确。

英文:

I am getting the exception o.h.e.j.s.SqlExceptionHelper | Bad value for type int : 9dac4fd2-a04c-4be7-976b-d880a43ea25a. It seems to want to put a UUID in an Integer field here.

I have the following tables, which admittedly are a bit complex in terms of compound keys:

CREATE TABLE public.event (
    id uuid NOT NULL,
    ...
    CONSTRAINT event_pkey PRIMARY KEY (id)
);

CREATE TABLE public.condition_set (
    api_id uuid NOT NULL,
    version integer NOT NULL,
    ...,
    CONSTRAINT condition_set_pkey PRIMARY KEY (api_id, version)
);

CREATE TABLE public.condition_set_event (
    condition_set_api_id uuid NOT NULL,
    condition_set_version integer NOT NULL,
    event_id uuid NOT NULL,
    CONSTRAINT condition_set_event_pkey PRIMARY KEY (condition_set_api_id, condition_set_version, event_id),
    CONSTRAINT fk_condition_set FOREIGN KEY (condition_set_api_id, condition_set_version) REFERENCES public.condition_set(api_id, version) ON DELETE CASCADE,
    CONSTRAINT fk_event FOREIGN KEY (event_id) REFERENCES public.event(id) ON DELETE CASCADE
);

In my model I have the Event class which is fairly straightforward. The ConditionSet class has a compound primary key matching the database structure, as follows:

@Entity
public class ConditionSet {

    @EmbeddedId
    private ConditionSetId id;
}

which looks like:

@Embeddable
public class ConditionSetId implements Serializable {

    private static final long serialVersionUID = 8110138933878596476L;

    private UUID apiId;
    private Integer version;

}

The tricky part is the ConditionSetEvent junction table which ALSO consists of a compound key, of which one is the compound key of ConditionSet

@Entity
public class ConditionSetEvent {

    @EmbeddedId
    private ConditionSetEventId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @MapsId(&quot;conditionSetId&quot;)
    @JoinColumns(foreignKey = @ForeignKey(name = &quot;fk_condition_set&quot;), value = {
        @JoinColumn(nullable = false, name = &quot;conditionSetApiId&quot;),
        @JoinColumn(nullable = false, name = &quot;conditionSetVersion&quot;)
    })
    private ConditionSet conditionSet;

    @ManyToOne(fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @MapsId(&quot;eventId&quot;)
    @JoinColumn(foreignKey = @ForeignKey(name = &quot;fk_event&quot;))
    private Event event;

    public ConditionSetEvent(ConditionSet conditionSet, Event event) {
        this.conditionSet = conditionSet;
        this.event = event;
        this.id = new ConditionSetEventId(conditionSet.getId(), event.getId());
    }
}

with its EmbeddedId:

@Embeddable
public class ConditionSetEventId implements Serializable {

    private static final long serialVersionUID = -6269791751266804667L;

    private ConditionSetId conditionSetId;
    private UUID eventId;
}

However, if I try to query this junction table with this repository method:

public interface ConditionSetEventRepository extends JpaRepository&lt;ConditionSetEvent, ConditionSetEventId&gt; {

    @Query(&quot;select cse from ConditionSetEvent cse where cse.id.eventId = :eventId&quot;)
    List&lt;ConditionSetEvent&gt; findByEventId(UUID eventId);
}

then I get the error as mentioned on top (where the uuid in the exception is a valid ConditionSet.apiId, but that somehow seems to be re-used.

With trace logging:

DEBUG | org.hibernate.SQL | select conditions0_.condition_set_api_id as conditio0_8_, conditions0_.event_id as event_id1_8_, conditions0_.condition_set_api_id as conditio2_8_, conditions0_.condition_set_version as conditio3_8_ from condition_set_event conditions0_ where conditions0_.event_id=?
TRACE | o.h.t.d.sql.BasicBinder | binding parameter [1] as [OTHER] - [be1ec45d-6533-4e77-98b7-f9a357cda052]
TRACE | o.h.t.d.s.BasicExtractor | extracted value ([conditio0_8_] : [OTHER]) - [9dac4fd2-a04c-4be7-976b-d880a43ea25a]
WARN | o.h.e.j.s.SqlExceptionHelper | SQL Error: 0, SQLState: 22003
ERROR | o.h.e.j.s.SqlExceptionHelper | Bad value for type int : 9dac4fd2-a04c-4be7-976b-d880a43ea25a

So it does manage to extract that UUID value initially (the last trace line), but on the next step (for the Integer) it still is trying to use the UUID instead of the Integer.

Am I doing something wrong here?

答案1

得分: 1

I don't think you need the @JoinColumns and it is messing up which id column maps to which id field in ConditionSetEventId.

@Entity
public class ConditionSetEvent {

  @EmbeddedId
  private ConditionSetEventId id;

  @ManyToOne(fetch = FetchType.LAZY)
  @OnDelete(action = OnDeleteAction.CASCADE)
  @MapsId("conditionSetId")
  private ConditionSet conditionSet;
  // Other code...
}
英文:

I don't think you need the @JoinColumns and it is messing up which id column maps to which id field in ConditionSetEventId

    @Entity
    public class ConditionSetEvent {

      @EmbeddedId
      private ConditionSetEventId id;

      @ManyToOne(fetch = FetchType.LAZY)
      @OnDelete(action = OnDeleteAction.CASCADE)
      @MapsId(&quot;conditionSetId&quot;)
      private ConditionSet conditionSet;
      ....

huangapple
  • 本文由 发表于 2020年8月3日 22:39:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63231507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定