Проблема столбца дискриминатора JPA - PullRequest
1 голос
/ 16 января 2011

Привет всем. У меня есть этот набор классов:

@Entity
@Table(name = "S_MC_CC_RAPPORTI")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="COD_TIPORAPPORTO",
                     discriminatorType=DiscriminatorType.CHAR, length=1)
public abstract class Rapporto implements Serializable {

  private static final long serialVersionUID = -5567166522882040440L;

  @Id
  @Column(name = "COD_RAPPORTO")  
  protected Long codiceRapporto;

И этот подкласс:

@Entity
@Table(name="S_MC_CC_CCCLIENTI")
@DiscriminatorValue("1 ")
public class ContoCorrente extends Rapporto {
  private static final long serialVersionUID = -3380622649760983262L;

  @Column(name = "DESC_DIVISA")
  private String divisa;

Проблема в значении дискриминатора: в таблице столбец - CHAR (2).

Когда я делаю getItemById для подкласса, все работает нормально: это сгенерированный eclipselink sql: (я заменил определение столбца на * для удобства чтения)

[EL Fine]: 2011-01-16 16:01:14.531--ServerSession(5230193)--Connection(11601738)--Thread(Thread[main,5,main])--  SELECT * FROM S_MC_CC_RAPPORTI t0, S_MC_CC_CCCLIENTI t1 WHERE ((t0.COD_RAPPORTO = ?) AND ((t1.COD_RAPPORTO = t0.COD_RAPPORTO) AND (t0.COD_TIPORAPPORTO = ?)))
 bind => [1120676, 1 ]

Если я изменю @DiscriminatorValue("1"), удалив пробел, данные не найдены: это относительный сгенерированный sql

[EL Fine]: 2011-01-16 16:03:46.671--ServerSession(5230193)--Connection(11601738)--Thread(Thread[main,5,main])--SELECT * FROM S_MC_CC_RAPPORTI t0, S_MC_CC_CCCLIENTI t1 WHERE ((t0.COD_RAPPORTO = ?) AND ((t1.COD_RAPPORTO = t0.COD_RAPPORTO) AND (t0.COD_TIPORAPPORTO = ?)))
 bind => [1120676, 1]

Обратите внимание, что два запроса отлично работают с TOAD: оба t0.COD_TIPORAPPORTO = '1' один, даже t0.COD_TIPORAPPORTO = '1'.

ОК: я думаю, что @DiscriminatorValue("1 ") правильный.

Теперь я связываю многих со многими с суперклассом Раппорто, как описано здесь

Если я получу @DiscriminatorValue("1 "), я получу

[EL Warning]: 2011-01-16 16:09:33.421--ServerSession(29839159)--Thread(Thread[main,5,main])--Exception [EclipseLink-43] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [1] of type [class java.lang.String].
Descriptor: RelationalDescriptor(it.alten.intesasanpaolo.contratto.domain.core.rapporto.Rapporto --> [DatabaseTable(S_MC_CC_RAPPORTI)])

Если я изменяю @DiscriminatorValue("1"), удаляя пробел, все работает нормально, но я не получаю данных (даже если данные присутствуют в БД).

Я не знаю, что делать .... Есть идеи?

С уважением

Massimo

Ответы [ 2 ]

2 голосов
/ 17 января 2011

Кажется, в вашей базе данных проблема сравнения символов с пробелами при использовании привязки. Какую базу данных вы используете?

Есть несколько возможных решений, во-первых, я бы посоветовался с вашим драйвером JDBC, чтобы выяснить, есть ли в нем какие-либо исправления или варианты для решения этой проблемы.

Один из вариантов - установить "eclipselink.jdbc.bind-parameters" = "false" в вашем файле persistence.xml, это должно решить проблему.

Другое решение состоит в том, чтобы отключить обрезку символов в EclipseLink (это, кажется, не подвержено свойствам персистентности JPA (пожалуйста, зарегистрируйте ошибку), поэтому вам нужно использовать SessionCustomizer для ее установки) session.getLogin () setShouldTrimStrings (ложь).

Более сложное решение - использовать DescriptorCustomizer, чтобы установить собственный дескриптор ClassExtractor для дескриптора, чтобы использовать собственный код для определения класса.

Если вы можете изменить данные, то я бы порекомендовал просто обновить любое «1» до «01», тогда вы можете просто использовать «01» в качестве индикатора.

2 голосов
/ 16 января 2011

Похоже, что значения в вашей базе данных содержат завершающий пробел.Я бы предложил выполнить запрос к таблице и удалить конечные пробелы.Тогда значение дискриминатора будет "1" (без пробела)

На самом деле, если вы все равно собираетесь использовать числа, вы должны использовать DiscriminatorType.INTEGER

...