EclipseLink: сбой сопоставления ManyToOne со стратегией наследования SINGLE_TABLE - PullRequest
0 голосов
/ 25 января 2019

Я работаю над переносом проекта Kodo JDO на EclipseLink и застрял, пытаясь отобразить объект наследования SINGLE_TABLE на другой объект. Я получаю "Преобразование не удалось при преобразовании значения nvarchar 'Audit' в тип данных int" и не знаю, как это исправить.

  1. Как сопоставить / объединить наследование одной таблицы с другим объектом?
  2. Как получить коллекцию подклассов наследования одной таблицы

Пожалуйста, помогите.

Вот так выглядит моя база данных:

  • Таблица аудита: содержит информацию аудита для пользователя.

    • Audit_id является ключом PK и имеет столбец дискриминатора.
    • Если значение дискриминатора типа int. 1 для деталей адреса и 2 для деталей телефона.
    • Один пользователь может иметь более одной записи аудита. Поэтому мне нужно получить коллекцию.
  • Таблица пользователей -> user_id - это PK.

    • В столбце хранится идентификатор аудита вместо строки. Идентификатор аудита указывает на самое последнее изменение.

У идентификатора пользователя 100 есть 2 строки аудита для номера телефона. Я не мог получить коллекцию результатов. База данных - Пример данных

Базовый класс:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
@DiscriminatorColumn(name = "type")
@Table(name = "audit")
@NamedQuery(name = "Audit.findAll", query = "SELECT m FROM Audit m")
public  class Audit implements Serializable
{
  @Id
  @GeneratedValue(strategy = GenerationType.TABLE)
  @Column(name = "audit_id")
  private int auditId;

  @Column(name = "user_id")
  private int userId;

  @OneToMany(mappedBy = "addressAudit1")
  private List<User> User;

  //Getters and Setters are defined.
}

Подкласс 1:

@Entity
@DiscriminatorValue("1")
public class Address extends Audit
{
  @Column(name = "street_addr1")
  private String streetAddr1;

  @Column(name = "street_addr2")
  private String streetAddr2;

  //Getters and Setters are defined.
}

Подкласс 2:

@Entity
@DiscriminatorValue("2")
public class Phone extends Audit
{
  @Column(name = "home_phone")
  private String homePhone;

  @Column(name = "home_phone_ext")
  private String homePhoneExt;

  @Column(name = "work_phone")
  private String workPhone;

  @Column(name = "work_phone_ext")
  private String workPhoneExt;

  //Getters and Setters are defined.
}

Класс пользователя

@Entity
@Table(name = "user")
@NamedQuery(name = "User.findAll", query = "SELECT m FROM User m")
public class User implements Serializable
{
  @Id
  @GeneratedValue(strategy = GenerationType.TABLE)
  @Column(name = "user_id")
  private int UserId;

*//Below code is causing issue*
  @ManyToOne
  @JoinColumn(name = "CURRENT_STREET")
  private Audit addressAudit1;

  //Getters and Setters are defined.
}

UseCase 1. Мне нужно искать пользователя по идентификатору. Вот как я ищу

public static User getUserForId(long userID, EntityManagerFactory emf) throws Exception
  {
    User user = null;
    EntityManager em = null;
    try
    {
      em = emf.createEntityManager();
      TypedQuery<User> q = em.createQuery("select u from " + User.class.getName() + " u where u.userId = :userIndex", User.class);
      q.setParameter("userIndex", userID);
      List<User> userList = q.getResultList();
      if (userList.size() > 0)
      {
        Iterator<User> userItr = userList.iterator();
        if (userItr.hasNext())
        {
          user = userItr.next();
        }
      }
    }
    catch (Exception e)
    {
      logger.error(e.getMessage());
      throw new Exception(e.getMessage());
    }
    finally
    {
      em.close();
    }
    return user;
  }

Исключение выдается в q.getResultList ().

Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the nvarchar value 'Audit' to data type int.
Error Code: 245
Call: SELECT audit_id, type, JDOVERSION, user_id FROM audit WHERE ((audit_id = ?) AND (type = ?))
    bind => [2 parameters bound]
Query: ReadObjectQuery(name="addressAudit1" referenceClass=Audit )

ПРИМЕЧАНИЕ. То же самое работает, когда я использую аннотации @embedded и @embeddable. Я отказался от этого, потому что я не могу получить сбор аудитов.

...