We're updating the issue view to help you get more done. 

IllegalArgumentException when restricting query by part of a composite primary key

Description

I have a simple entity with a composite primary key:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 @Entity @Table(name = "person_conversation_meta") @IdClass(ConversationMeta.Id.class) public class ConversationMeta { public static class Id implements Serializable { private int conversation; private int person; public Id() { } public Id(int conversation, int person) { this.conversation = conversation; this.person = person; } public int getConversation() { return conversation; } public void setConversation(int conversation) { this.conversation = conversation; } public int getPerson() { return person; } public void setPerson(int person) { this.person = person; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Id id = (Id)o; if (conversation != id.conversation) return false; if (person != id.person) return false; return true; } @Override public int hashCode() { int result = conversation; result = 31 * result + person; return result; } } @javax.persistence.Id @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "person_id", nullable = false) private Person person; @javax.persistence.Id @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name = "conversation_id", nullable = false) private Conversation conversation; @Column(name = "is_read", nullable = false) private boolean read; @Column(nullable = false) private boolean starred; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public Conversation getConversation() { return conversation; } public void setConversation(Conversation conversation) { this.conversation = conversation; } public boolean isRead() { return read; } public void setRead(boolean read) { this.read = read; } public boolean isStarred() { return starred; } public void setStarred(boolean starred) { this.starred = starred; } }

Now I want to create a query to get all ConversationMeta for a particular Conversation:

1 2 3 CriteriaQuery<ConversationMeta> criteriaQuery = criteriaBuilder.createQuery(ConversationMeta.class); Root<ConversationMeta> conversationMeta = criteriaQuery.from(ConversationMeta.class); criteriaQuery.where(criteriaBuilder.equal(conversationMeta.get(ConversationMeta_.conversation), conversation));

The criteriaBuilder.equal(conversationMeta.get(ConversationMeta_.conversation), conversation) fails with IllegalArgumentException: Unaware how to convert value. The ConversationMeta_ metamodel class appears to be generating correctly, listing the conversation attribute as SingularAttribute<ConversationMeta, Conversation> which is why I'm checking for equality with a Conversation and not an int. But the attribute in reality has a javaType of int, which is why the Conversation entity is being converted.

Changing the ConversationMeta.Id class to contain Conversation and Person entities, rather than {{int}}s is a fine workaround. I just wanted to record this odd behavior.

Environment

None

Status

Assignee

Unassigned

Reporter

Tim Whitbeck

Fix versions

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

4.3.5

Priority

Minor