Неверный TypeDescriptor при использовании JoinColumns в составном ключе

Я ударился головой, пытаясь понять, что случилось со следующим отображением. Я понимаю, что следующее сопоставление не идеально подходит для ORM, но то, как база данных, и я не могу изменить ее структуру. Я использую JPA 2.1 и Hibernate 5.0.2.Final.

@MappedSuperclass    
public abstract class BaseEntity<T extends Serializable> implements Serializable {

    protected T id;

    @Id
    public T getId() {
        return id;
    }

    protected void setId(T id) {
        this.id = id;
    }
}

@Table(name = "campaign")
@AttributeOverride(name = "id", column = @Column(name = "campaign_id") )
public class Campaign extends BaseEntity<String> {
    // attributes, getters and setters
}

@Embeddable
public class CampaignBroadcastPK implements Serializable {

    @ManyToOne
    @JoinColumn(name = "campaign_id", insertable = false, updatable = false)
    private Campaign campaign;

    @Column(name = "broadcast_date")
    private LocalDate broadcastDate;

    // getters and setters
}

@Entity
@Table(name = "campaign_broadcast")
public class CampaignBroadcast implements Serializable {

    @EmbeddedId
    private CampaignBroadcastPK id;

    // attributes, getters and setters
}

@Embeddable
public class CampaignBroadcastProcessPK implements Serializable {

   @ManyToOne
   @JoinColumns({ 
       @JoinColumn(name = "campaign_id", insertable = false, updatable = false),
       @JoinColumn(name = "broadcast_date", insertable = false, updatable = false) 
    })
    private CampaignBroadcast broadcast;

    @Column(name = "process_date)
    private LocalDate processDate;

    // getters and setters
}

@Entity
@Table(name = "campaign_broadcast_process")
public class CampaignBroadcastProcess implements Serializable {

    @EmbeddedId
    private CampaignBroadcastProcessPK id;

    // attributes, getters and setters
}

Помимо этой структуры, у меня также есть конвертер для обработки LocalDate на java.sql.Date, который аннотируется с помощью autoApply=true.

Когда я пытаюсь загрузить CampaignBroadcastProcess через entityManager.find(), hibernate пытается преобразовать campaign_id в Date, даже если он отображается как String, в результате чего java.sql.Date выдает IllegalStateException, потому что строка, переданная valueOf не является допустимой строкой даты.

Я подозрительный Hibernate смешивает типы JoinColumns на CampaignBroadcastProcessPK, обрабатывая их как LocalDate.

Кто-нибудь когда-либо сталкивался с этой проблемой?

Ответ 1

Я не совсем уверен, почему, но изменение порядка двух @JoinColum решило проблему. Отображение теперь выглядит следующим образом:

@ManyToOne
@JoinColumns({ 
    @JoinColumn(name = "broadcast_date", insertable = false, updatable = false),
    @JoinColumn(name = "campaign_id", insertable = false, updatable = false)     
})
private CampaignBroadcast broadcast;

Ответ 2

Попробуйте добавить явное referatedColumnName к вашему @JoinColumn. Обнаруженная вами ошибка может быть вызвана неправильным неявным отображением столбцов составных ключей

@ManyToOne
@JoinColumns({
    @JoinColumn(name = "campaign_id", referencedColumnName = "campaign_id", ...),
    @JoinColumn(name = "broadcast_date", referencedColumnName = "broadcast_date", ...) })
private CampaignBroadcast broadcast;

Ответ 3

Я думаю, это связано с тем, что hibernate выбрал первый тип данных, который был типом данных, и сопоставил его с столбцом Join