0

I have 2 entities that have Id's annotated but those Id's aren the primary keys in the tables. I am still mapping the PK's in to the entity for now to limit the initial impact of the change. But the association table that uses the PK's to associate the many to many relationship is throwing the following error:

java.lang.IllegalArgumentException: Provided id of the wrong type for class. Expected: class java.util.UUID, got class java.lang.Long

The entity @Id is the UUID but the table PK which is a Long is mapped as the @JoinColumn

The composite key for the association entity

@Embeddable
public class CustomerAccountId implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "user_id", nullable = false)
    private Long customerId;

    @Column(name = "account_id", nullable = false)
    private Long accountId;

The association entity:

    @EmbeddedId
@AttributeOverrides({
    @AttributeOverride(name = "customerId", column = @Column(name = "user_id", nullable = false)),
    @AttributeOverride(name = "accountId", column = @Column(name = "account_id", nullable = false))
})
private CustomerAccountId id;

@ManyToOne
@JoinColumn(name = "user_id", insertable = false, updatable = false, referencedColumnName = "user_id")
private Customer customer;

@ManyToOne
@JoinColumn(name = "account_id", insertable = false, updatable = false, referencedColumnName = "id")
private Account account;

The failing entity:

@Column(name = "user_id")
private Long serialId;  // also the primary key in the table

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@org.hibernate.annotations.Type(type="pg-uuid")
@Column(name = "uid", updatable = false)
private UUID id;

Does anyone know if this is even possible? or am I going to be forced to update the content in the association table when I push this change?

peekay
  • 1,259
  • 2
  • 25
  • 49

2 Answers2

0
  • put @Id and @GeneratedValue on the field that represent the table data then hibernate will map a long (sgbd) whit a long (table)

or

  • your (sgbd) table data type must be compatible with the (java) uuid type.

Why these 2 keys on your table?

I think it's not possible to have 2 PK for one entity. At most you can have a composite key base on your serialID and the UUID.

see How to map a composite key with Hibernate? for that

Or mark as @Id the real PK in the SGBD. Use the other in Java as a classic value in the table's point of view

Community
  • 1
  • 1
Tokazio
  • 516
  • 2
  • 18
  • I don't want to expose the serial Id column as it is a security risk and to avoid a performance hit for using the UUID as the PK I wanted to keep the serial Id as the PK. The serial Id is still being mapped to the entity so I can do the work in phases but I do not want it to be the entity Id. – peekay Sep 28 '16 at 21:26
  • if i correctly understand, you don't want to allow the id modification? see http://stackoverflow.com/a/2217064/2710704 – Tokazio Sep 28 '16 at 21:43
  • I originally used the sequential Id's everywhere. Now after a security audit I am converting to UUID's, but I don't want to use UUIDs as PK's due to potential performance issues. – peekay Sep 28 '16 at 21:45
  • then your @Id goes to your serialId as PK internal use. But i still don't understand the use of uuid if you keep serialId – Tokazio Sep 28 '16 at 21:55
0

The solution I decided to go with is the following:

@ManyToOne
@JoinColumns ( value = {
    @JoinColumn(name = "user_id", insertable = false, updatable = false, referencedColumnName = "user_id"),
    @JoinColumn(name = "user_uid", insertable = false, updatable = false, referencedColumnName = "uid")
})
private Customer customer;

In a nutshell I simply added the UUID to the association table and used both columns for the Customer Entity.

To address @Tokazio's question about using UUID and serial Id, the data warehouse conversion is impacted significantly so I need to slowly move from serial Id's to UUID's to minimize impacts and prevent outages.

peekay
  • 1,259
  • 2
  • 25
  • 49