Hibernate: class org.hibernate.type.internal.NamedBasicTypeImpl cannot be cast to class org.hibernate.metamodel.mapping
04.10.2022, 00:17. Показов 1156. Ответов 0
Доброго времени суток!
Сталкиваюсь с такой ошибкой при попытке получить результат HQL запроса с join-ом:
| Java | 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
| Hibernate: insert into ships (characteristics, creation_year, dock, model, title) values (?, ?, ?, ?, ?)
окт. 04, 2022 12:05:57 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: 23505
окт. 04, 2022 12:05:57 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности "ships_pkey"
Подробности: Ключ "(title)=(Pobeda)" уже существует.
окт. 04, 2022 12:05:57 AM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Hibernate: insert into races (destination, source, arrival_date, ship_name, start_date) values (?, ?, ?, ?, ?)
Exception in thread "main" java.lang.ClassCastException: class org.hibernate.type.internal.NamedBasicTypeImpl cannot be cast to class org.hibernate.metamodel.mapping.EntityValuedModelPart (org.hibernate.type.internal.NamedBasicTypeImpl and org.hibernate.metamodel.mapping.EntityValuedModelPart are in unnamed module of loader 'app')
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitTableGroup(BaseSqmToSqlAstConverter.java:3491)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQualifiedAttributeJoin(BaseSqmToSqlAstConverter.java:3426)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQualifiedAttributeJoin(BaseSqmToSqlAstConverter.java:414)
at org.hibernate.query.sqm.tree.domain.AbstractSqmAttributeJoin.accept(AbstractSqmAttributeJoin.java:131)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitComparisonPredicate(BaseSqmToSqlAstConverter.java:6517)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitComparisonPredicate(BaseSqmToSqlAstConverter.java:414)
at org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate.accept(SqmComparisonPredicate.java:104)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitWhereClause(BaseSqmToSqlAstConverter.java:2262)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:1833)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:414)
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.accept(SqmQuerySpec.java:122)
at org.hibernate.query.sqm.spi.BaseSemanticQueryWalker.visitQueryPart(BaseSemanticQueryWalker.java:213)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQueryPart(BaseSqmToSqlAstConverter.java:1689)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:1487)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:414)
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.accept(SqmSelectStatement.java:199)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.translate(BaseSqmToSqlAstConverter.java:709)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:350)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:270)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:246)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:537)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:363)
at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:987)
at ru.sokolovda.dao.RaceDAO.findShipLastRaceWithShipModel(RaceDAO.java:49)
at ru.sokolovda.services.RaceService.findLastShipRaceWithShipModel(RaceService.java:20)
at ru.sokolovda.Main.main(Main.java:34) |
|
Не могу понять, что во что пытается скастовать Hibernate, и почему у него это не получается. Прошу помочь в решении проблемы (может что-то не так реализовано в классах моделей, из-за чего не работает приведение типов)!
Main класс:
| Java | 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
| package ru.sokolovda;
import ru.sokolovda.models.Race;
import ru.sokolovda.models.Ship;
import ru.sokolovda.services.RaceService;
import ru.sokolovda.services.ShipService;
import java.io.InputStream;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Создаём корабль
String shipCharacteristics = readFileToString("Characteristics.json");
Ship ship = new Ship("Pobeda", "крейсер", "Сочи", "1989", shipCharacteristics);
ShipService shipService = new ShipService();
shipService.saveShip(ship);
// Создаем рейс
Date startDate = new Date();
Date arrivalDate = new Date();
Race race = new Race(ship, startDate, arrivalDate, "Sochi", "Helsinki");
RaceService raceService = new RaceService();
raceService.saveRace(race);
// Получаем последний рейс по названию корабля, а также модель этого корабля
Race pobedaLastRace = raceService.findLastShipRaceWithShipModel("Pobeda");
System.out.println(pobedaLastRace.getRacePK().getShip().getModel());
} |
|
Race:
| Java | 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
| package ru.sokolovda.models;
import jakarta.persistence.*;
import lombok.*;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
@Entity
@Table(name = "races")
@NoArgsConstructor
@Getter
@Setter
public class Race implements Serializable {
@EmbeddedId
private RacePK racePK;
@Column(name = "source")
private String source;
@Column(name = "destination")
private String destination;
public Race(Ship shipName, Date startDate, Date arrivalDate, String source, String destination) {
this.source = source;
this.destination = destination;
this.racePK = new RacePK(shipName, startDate, arrivalDate);
}
// Только для практики. На деле, для уникальности достаточно поля id
@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class RacePK implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ship_name")
private Ship ship;
@Column(name = "start_date")
@Temporal(TemporalType.TIMESTAMP)
private Date startDate;
@Column(name = "arrival_date")
@Temporal(TemporalType.TIMESTAMP)
private Date arrivalDate;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RacePK racePK = (RacePK) o;
return Objects.equals(ship, racePK.ship) && Objects.equals(startDate, racePK.startDate) && Objects.equals(arrivalDate, racePK.arrivalDate);
}
@Override
public int hashCode() {
return Objects.hash(ship, startDate, arrivalDate);
}
}
} |
|
Ship
| Java | 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
| package ru.sokolovda.models;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.util.List;
@Entity
@Table(name = "ships")
@NoArgsConstructor
@Getter
public class Ship {
@Id
@Column(name = "title", nullable = false)
private String title;
@Column(name = "model", nullable = false)
private String model;
@Column(name = "dock", nullable = false)
private String dock;
@Column(name = "creation_year", nullable = false)
private String creationYear;
// Данная аннотация работает только с версии Hibernate 6
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "characteristics", nullable = false)
private ShipCharacteristics characteristicsJson;
@OneToMany(mappedBy = "racePK.ship", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Race> races;
public Ship(String title, String model, String dock, String creationYear) {
this.title = title;
this.model = model;
this.dock = dock;
this.creationYear = creationYear;
}
public Ship(String title, String model, String dock, String creationYear, String characteristicsJson) {
this.title = title;
this.model = model;
this.dock = dock;
this.creationYear = creationYear;
this.characteristicsJson = characteristicsToPOJO(characteristicsJson);
}
public ShipCharacteristics characteristicsToPOJO(String characteristicsJson) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(characteristicsJson, ShipCharacteristics.class);
} catch(JsonProcessingException ex) {
System.out.println(ex.getMessage());
return new ShipCharacteristics();
}
}
} |
|
RaceDAO
| Java | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| package ru.sokolovda.dao;
import ...
public class RaceDAO {
// Выводит информацию о последнем рейсе данного корабля (по его названию), с названием модели корабля
public Race findShipLastRaceWithShipModel(String shipName) {
Session session = HibernateSessionFactory.getSessionFactory().openSession();
String query = "from Race as r join fetch r.racePK.ship where r.racePK.ship = '" + shipName + "'";
// По идее, ошибка возникает тут, при проваливании в метод list()
List races = session.createQuery(query).list();
Object[] row = (Object[])races.get(0);
Race race = (Race)row[0];
Ship ship = (Ship)row[1];
session.close();
return race;
}
// CRUD methods ...
} |
|
0
|