Я написал мыльные сервисы, в которых данные читаются из базы данных через спящий режим.Я использовал запросы JPA Criteria и статическую метамодель JPA в запросах для получения данных.Я генерирую метамодель с помощью плагина hibernate-jpamodelgen.При обработке запроса, когда служба создает запрос на чтение данных из базы данных, тогда SingularAttributes первичных ключей в классах статической модели JPA равны нулю (я не знаю, почему они не заполняются, хотя заполняются другие атрибуты, которые не являются первичными ключами), и этогенерирует исключение NullPointerException.
Мои классы:
@MappedSuperclass
public abstract class ReadModel implements Serializable, Cloneable {
public ReadModel() {
}
@Column(name = "customerId")
private BigInteger customerId;
@Id
@Column(name = "device_id")
private BigInteger deviceId;
@Column(name = "date")
private Date date;
@Column(name = "time")
private Time time;
@Id
@Column(name = "device_time")
private Timestamp deviceTime;
public BigInteger getCustomerId() {
return customerId;
}
public ReadModel setCustomerId(BigInteger customerId) {
this.customerId = customerId;
return this;
}
public BigInteger getId() {
return deviceId;
}
public ReadModel setId(BigInteger deviceId) {
this.deviceId = deviceId;
return this;
}
public Date getDate() {
return date;
}
public ReadModel setDate(Date date) {
this.date = date;
return this;
}
public Time getTime() {
return time;
}
public ReadModel setTime(Time time) {
this.time = time;
return this;
}
public Timestamp getDeviceTime() {
return deviceTime;
}
public ReadModel setDeviceTime(Timestamp deviceTime) {
this.deviceTime = deviceTime;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ReadModel that = (ReadModel) o;
return Objects.equals(getId(), that.getId()) &&
Objects.equals(getDeviceTime(), that.getDeviceTime());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getDeviceTime());
}
}
И второй класс:
@Entity
@Table(name = "device_data")
public class DeviceData extends ReadModel implements Serializable,Cloneable {
public DeviceDataRead() {
}
}
И соответствующие сгенерированные метамодели JPA-статики:
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(ReadModel.class)
public abstract class ReadModel_ {
public static volatile SingularAttribute<ReadModel, Time> time;
public static volatile SingularAttribute<ReadModel, BigInteger> customerId;
public static volatile SingularAttribute<ReadModel, BigInteger> deviceId;
public static volatile SingularAttribute<ReadModel, Timestamp> deviceTime;
public static volatile SingularAttribute<ReadModel, Date> date;
public static final String TIME = "time";
public static final String CUSTOMER_ID = "customerId";
public static final String DEVICE_ID = "deviceId";
public static final String DEVICE_TIME = "deviceTime";
public static final String DATE = "date";
}
И
@StaticMetamodel(DeviceData.class)
public abstract class DeviceData_ extends ReadModel_ {
public DeviceData_() {
}
}
Мои зависимости hibernare:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<properties>
<hibernate.version>5.3.1.Final</hibernate.version>
</properties>
И вот мои служебные методы: функция createProperties () возвращает свойства Object.
public class HibernateUtils {
private static SessionFactory factory = null;
public static SessionFactory getSessionFactory(){
if (factory == null) {
factory = buildSessionFactoryFromAnnotatedClasses(HOST, PORT, DB_NAME, PROTOCOL_MY_SQL,
USER_NAME, PASSWORD, CONNECTION_MIN_POOL_SIZE_FOR_PARTICULAR_CLASS_VALUE,
CONNECTION_MAX_POOL_SIZE_FOR_PARTICULAR_CLASS_VALUE, Arrays.asList(DeviceData););
}
return factory;
}
public static SessionFactory buildSessionFactoryFromAnnotatedClasses(String host,
Integer port, String dbName, String protocol, String userName, String password,
Integer minPoolSize, Integer maxPoolSize, List<Class> annotatedClassNames) {
StandardServiceRegistry standardRegistry =
new StandardServiceRegistryBuilder().applySettings(createProperties(
host, port, dbName, protocol, userName, password, minPoolSize, maxPoolSize)
.getProperties()).build();
MetadataSources sources = new MetadataSources(standardRegistry);
annotatedClassNames.forEach(sources::addAnnotatedClass);
Metadata metaData = sources.getMetadataBuilder().build();
return metaData.getSessionFactoryBuilder().build();
}
}
И вот запрос:
ReadModel_.deviceId и ReadModel_.deviceTime оба имеют нулевое значение, но все остальные атрибуты заполнены (ReadModel_.CUSTOMER_ID, ReadModel_.DATE, ReadModel_.TIME не являются нулевыми)
try (Session session = HibernateUtils.getSessionFactory().openSession()) {
SingularAttribute<ReadModel, BigInteger> deviceId = ReadModel_.deviceId;//this is null
SingularAttribute<ReadModel, Timestamp> devicetime = ReadModel_.deviceTime;//this is null
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<DeviceData> cq = cb.createQuery(DeviceData.class);
Root<DeviceData> root = cq.from(DeviceData.class);
List<Predicate> conditions = new ArrayList<>();
conditions.add(cb.isTrue(root.get(deviceId).in(devicList)));//root.get(deviceId) throws NullPointerException
conditions.add(cb.greaterThanOrEqualTo(root.get(devicetime), dataStartTime()));
cq.where(conditions.toArray(new Predicate[]{})).orderBy(cb.asc(root.get(devicetime)));
Query query= session.createQuery(cq);
}
Я застрял очень плохо.Может кто-нибудь сказать мне, что я должен делать?заранее спасибо.