Я реализую API персистентности, используя Hibernate JPA.Я использую PostgreSQL 10.4 и храню данные как JSONB.Я делюсь своей реализацией Hibernate и Entity, пожалуйста, укажите, почему я получаю исключение ниже.
Я следую этой замечательной статье, чтобы реализовать пользовательский тип UserType, поскольку Hibernate не поддерживает тип данных PostgreSQL JSONB:https://www.thoughts -on-java.org / persist-postgresqls-jsonb-data-type-type-hibernate /
Мне удалось создать сопоставления сущностей и выполнить простой запрос Select и распечататьзначение, присвоенное сопоставлению.
Проблема заключается в том, что при выполнении операции фиксации транзакции я получаю следующее исключение:
22: 42: 35.218 [main] DEBUGorg.hibernate.engine.transaction.internal.TransactionImpl - rollback () вызывается для неактивной транзакции. Исключение в потоке «main».TransactionImpl.java:86) at com.postgres.main.TestMain.main (TestMain.java:41). Вызвано: javax.persistence.PersistenceException: org.hibernate.HibernateException: идентификатор экземпляра com.postgres.model.Alert было изменено с com.postgres.model.Alert@62794582 на com.postgres.model.Alert@c82ad22 в org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert (АннотацияEntityManagerImpl.java:1692) в org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert (AbstractEntityManagerImpl.java:1602) в org.hibernate.jpa.internal.TransactionImpl.commit (TransactionImp67.j ...) ...jЕще 1 Причина: org.hibernate.HibernateException: идентификатор экземпляра com.postgres.model.Alert был изменен с com.postgres.model.Alert@62794582 на com.postgres.model.Alert@c82ad22 в org.hibernate..java: 135) в org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities (AbstractFlushingEventListener.java:216) в org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExavecutions (AbstractFlistenja: 85) в org.hibernate.event.internal.DefaultFlushEventListener.onFlush (DefaultFlushEventListener.java:38) в org.hibernate.internal.SessionImpl.flush (SessionImpl.java:1295) в org.hibernate.internal.SessionIlmp(SessionImpl.java:468) в org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion (SessionImpl.java:3135) в org.hibernate.internal.SessionImpl.beforeTransactionCompletion (SessionImpl.java:2.ghb или org.jb).internal.JdbcCoordinatorImpl.beforeTransactionCompletion (JdbcCoordinatorImpl.java:485) в org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforecjj_tb_jl_cr.dllinternal.JdbcResourceLocalTransactionCoordinatorImpl.access $ 100 (JdbcResourceLocalTransactionCoordinatorImpl.java:38) в org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$ Транзакция) ... еще 1
Я также подписался на следующий пост, где люди поделились, как они исправили проблему, но это не помогло мне: Hibernate: Как исправить «идентификатор экземпляра, измененного с X на Y»?
Это объект оповещения:
@Entity
@IdClass(Alert.class)
@Table(name = "alert")
public class Alert implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "historyid")
private Character historyId;
@Id
@Column(name = "tenantname")
private Character tenantName;
@Column(name = "data")
@Type(type = "AlertJsonUserType")
private AlertJson alertJson;
public Character getHistoryId() {
return historyId;
}
public void setHistoryId(Character historyId) {
this.historyId = historyId;
}
public Character getTenantName() {
return tenantName;
}
public void setTenantName(Character tenantName) {
this.tenantName = tenantName;
}
public AlertJson getAlertJson() {
return alertJson;
}
public void setAlertJson(AlertJson alertJson) {
this.alertJson = alertJson;
}
}
Это объект для элемента JSONB в объекте оповещения
public class AlertJson implements Serializable
{
private static final long serialVersionUID = 1L;
@JsonProperty("DeviceId")
private String deviceId;
@JsonProperty("TenantName")
private String tenantName;
@JsonProperty("FocusPointId")
private List<FocusPointId> focusPointId;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
public List<FocusPointId> getFocusPointId() {
return focusPointId;
}
public void setFocusPointId(List<FocusPointId> focusPointId) {
this.focusPointId = focusPointId;
}
}
class FocusPointId
{
@JsonProperty("PartNumber")
private String partNumber;
@JsonProperty("SerialNumber")
private String serialNumber;
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
}
Ниже приведен фрагмент main (), где я создаю экземпляр EntityManager и выдаю запрос
public static void main(String[] args)
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Query alertQuery = em.createNativeQuery("SELECT * FROM \"A.01\".\"Alert\" where tenantname = 'TestUser-152'", Alert.class);
List<Alert> alertList = alertQuery.getResultList();
for(Alert jsonElement : alertList)
{
System.out.println("======> "+"Device: " + jsonElement.getAlertJson().getDeviceId() + " TenantName: " +jsonElement.getAlertJson().getTenantName());
}
em.getTransaction().commit();
emf.close();
}
Ниже приведена таблица описания и ограничения.
PK это и historyid, и имя арендатора.