Reputation: 2166
I have this object:
@Entity
@Table(name = "PERSONNE")
@NamedQuery(name = "Personne.findAll", query = "SELECT p FROM Personne p")
@Inheritance(strategy = InheritanceType.JOINED)
@ClassExtractor(PersonneClassExtractor.class)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
@ToString(of = { "personneId", "perId" })
@EqualsAndHashCode(of = { "personneId", "perId" })
public class Personne implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@ReturnInsert
@Column(name = "PERSONNE_ID")
protected Long personneId;
..
}
and this one:
@Entity
@Table(name = "ENFANT")
@NamedQuery(name = "Enfant.findAll", query = "SELECT e FROM Enfant e")
@PrimaryKeyJoinColumn(name = "PERSONNE_ID")
@Inheritance(strategy = InheritanceType.JOINED)
@Data
@SuperBuilder
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Audit
public class Enfant extends Personne {
private static final long serialVersionUID = 1L;
..
}
and this:
@Repository
public interface EnfantRepository extends PersonneBaseRepository<Enfant>,
JpaSpecificationExecutor<Enfant> {
@Query("SELECT e FROM Enfant e WHERE e.personneId = ?1")
Enfant findOne(Long enfantId);
..
}
and
@NoRepositoryBean
public interface PersonneBaseRepository<T extends Personne>
extends JpaRepository<T, Long> {
}
but when I do
Enfant enfant = enfantRepo.findOne(7L);
I have this error:
class com.mundos.model.persons.Personne cannot be cast to class com.mundos.model.persons.Enfant (com.mundos.model.persons.Personne and com.mundos.model.persons.Enfant are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @67cae0fe)
I also tried enfantRepo.findById
with the same result
Upvotes: 5
Views: 877
Reputation: 5622
Your error might be misleading, according to this stackoverflow unless you are explicitly casting in your code.
And not sure both are in same jar|library in your code (depends on your structure)!! ERROR: in unnamed module of loader
Try, This may help if devtools is in your classpath.
public static void main(final String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(Application.class, args);
}
OR
Exclude | Remove
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
Upvotes: 1
Reputation: 16374
The findOne
method provided by JpaSpecificationExecutor
contract and the implementation underneath (`SimpleJpaRepository) has seen some changes in different spring-data-jpa project versions.
While this is not clear given the reported error, but the runtime may be generating a new query on-fly that does not match your polymorphic structure (you can activate hibernate SQL logging to inspect these).
That being said, you are better off using the findById
and getById
ready alternatives instead of creating your own query-based method. You should remove your custom findOne
method out of your JpaRepository
declaration:
@Repository
public interface EnfantRepository extends PersonneBaseRepository<Enfant>, JpaSpecificationExecutor<Enfant> {
// ...
}
You are then able to query the Enfant
entity based on its identifier:
Enfant enfant = enfantRepo.findById(7L).orElseThrow(() -> new EntityNotFoundException(id));
Or simply bypassing the Optional
return value using the getById
alternative:
Enfant enfant = enfantRepo.getById(7L);
Upvotes: 1