HibernateException: идентификатор экземпляра был изменен с Alert @ 62794582 на Alert @ c82ad22 - PullRequest
0 голосов
/ 18 сентября 2018

Я реализую 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, и имя арендатора.

Table Describe

Table Constraints

1 Ответ

0 голосов
/ 18 сентября 2018

Я думаю, что у вас есть эта проблема, потому что вы неправильно используете аннотацию IdClass, вы должны создать отдельный класс AlertId, например, который будет содержать поля из вашего составного PK, и этот класс должен использоваться как параметр для IdClass аннотация

...