Hi everyone, I’m facing with some strange behavior when trying to introduce base entities in my project. I do not know it is bug or maybe I’m doing something wrong, but either way, here’s what I’m trying to do:
I have below classes structure:
The base interface for all persistable entites:
public interface Persistable<ID> extends Serializable {
ID getId();
void setId(ID id);
}
Abstract persistable implementation that’s just abstract class holding id property:
@Getter
@Setter
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {
private PK id;
}
Specific base class for entities with Long identifier:
@Setter
@Getter
@MappedSuperclass
public abstract class AbstractPersistableLong extends AbstractPersistable<Long> {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_generator")
public Long getId() {
return super.getId();
}
}
My super base for all auditable entities:
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditable<AUDITOR, PK extends Serializable> extends AbstractPersistable<PK>
implements Auditable<AUDITOR, PK, Instant> {
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false)
private Instant createdAt;
@CreatedBy
@Column(name = "created_by", nullable = false)
private String createdBy;
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at", nullable = false)
private Instant updatedAt;
@LastModifiedBy
@Column(name = "updated_by", nullable = false)
private String updatedBy;
}
And specific auditable base class for all entities with Long identifier:
@Getter
@Setter
@MappedSuperclass
public abstract class AbstractAuditableLong<AUDITOR> extends AbstractAuditable<AUDITOR, Long> {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_generator")
public Long getId() {
return super.getId();
}
}
And now here’s how I am using this base classes:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "item")
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@SequenceGenerator(name = "default_generator", sequenceName = "item_abstract_id_seq")
public abstract class ItemAbstract extends AbstractAuditableLong<String> implements Serializable {
@ManyToOne(fetch = FetchType.LAZY, targetEntity = ItemOwner.class)
@JoinColumn(name = "item_owner_id", nullable = false)
private ItemOwner itemOwner;
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "item_owner")
@SequenceGenerator(name = "default_generator", sequenceName = "seq")
public class ItemOwner extends AbstractPersistableLong {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "itemOwner")
private Set<ItemAbstract> items = new HashSet<>();
}
The error occurs while hibernate try to manage ItemOwner class. The full error looks like this:
Caused by: java.lang.ClassCastException: class org.hibernate.type.internal.BasicTypeImpl cannot be cast to class org.hibernate.type.BasicPluralType (org.hibernate.type.internal.BasicTypeImpl and org.hibernate.type.BasicPluralType are in unnamed module of loader ‘app’). And if I in ItemOwner don’t extend AbstarctPersistableLong and define Id filed by my hand error disappears, so is it expected behavior or is it bug?