2010-10-23 3 views
4

Использование реализации EclipseLink JPA2 (не уверен, что это совпадает с реализацией Hibernate)Почему JPA выбирает String для JoinColumn независимо от типов ключей?

У меня есть простая структура, в которой у организации есть контракты. Вот SQL я экспортируемые из Postgres, чтобы создать Организацию

CREATE TABLE organization (
    key bigint NOT NULL, 
    version integer 
); 

Если я указываю сторона договора Организации, как это:

@ManyToOne(optional=false) 
@JoinColumn(name="organization_key", referencedColumnName="key") 
private Organization organization; 

, а затем сбросить схему, я получаю это.

CREATE TABLE contract ( 
    key bigint NOT NULL, 
    version integer, 
    organization_key character varying(255), 
); 

Это не имеет смысла для меня, что он будет использовать символ изменяющегося (255) поле для ссылки на ключ организации. Я знаю, что могу использовать ColumnDefinition следующим образом:

@ManyToOne(optional=false) 
@JoinColumn(name="organization_key", referencedColumnName="key", columnDefinition="bigint NOT NULL") 
private Organization organization; 

получить тип BigInt вместо типа символов.

Неверно ли мне ожидать, что он получит правильный тип столбца? Я использую это неправильно или у меня неправильные ожидания? Ожидается ли, что мне придется каждый раз использовать функцию columnDefinition?

Update: Вот соответствующая информация от лица организации

@Entity 
@Table(name = "organization") 
@SequenceGenerator(name = "ORGANIZATION_SEQ_GEN", sequenceName = "ORGANIZATION_SEQUENCE") 
public class Organization 
     implements DataObject<Long> 
{ 

    /** 
    * key for this instance. Should be managed by JPA provider. 
    */ 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ORGANIZATION_SEQ_GEN") 
    private Long key; 

    /** 
    * JPA version column 
    */ 
    @Version 
    protected int version; 

    /** 
    * All contracts for this organization 
    */ 
    @OneToMany(mappedBy="organization") 
    @OrderBy("endDate DESC") 
    private List<Contract> contracts; 

    ... getters and setters   
} 

И вот Entity контракт

@Entity 
@Table(name = "contract") 
@SequenceGenerator(name = "CONTRACT_SEQ_GEN", sequenceName = "CONTRACT_SEQUENCE") 
public class Contract 
     implements DataObject<Long> 
{ 

    /** 
    * key for this instance. Should be managed by JPA provider. 
    */ 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CONTRACT_SEQ_GEN") 
    private Long key; 

    /** 
    * Organization that owns this contract, required. 
    */ 
    @ManyToOne(optional=false) 
    @JoinColumn(name="organization_key", referencedColumnName="key") 
    private Organization organization; 

    /** 
    * JPA version column 
    */ 
    @Version 
    protected int version; 

    ... getters and setters 
} 

ответ

3

ли это нереально для меня, чтобы ожидать его, чтобы получить правильный тип столбца?

Нет, это нереально, и текущий результат явно неожиданен.

Я использую это неправильно или у меня неправильные ожидания?

Ваши сопоставления не выглядят неправильно. Не могли бы вы просто попробовать следующее и подтвердить, что вы получите тот же результат (я просто опускаю referencedColumnName, который вам не нужно определять в любом случае)?

@Entity 
@Table(name = "contract") 
@SequenceGenerator(name = "CONTRACT_SEQ_GEN", sequenceName = "CONTRACT_SEQUENCE") 
public class Contract implements DataObject<Long> { 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CONTRACT_SEQ_GEN") 
    private Long key; 
    ... 
    @ManyToOne(optional=false) 
    @JoinColumn(name="organization_key") 
    private Organization organization; 
    ... 
} 

У меня нет PostgreSQL, я не могу попробовать себя.

Ожидается ли, что мне придется использовать columnDefinition каждый раз?

No.

+0

обновлен с соответствующей информацией от двух объектов. – digitaljoel

+0

@digitaljoel: Посмотрите мое обновление. Кстати, вы определили свойство 'eclipselink.target-database' в вашем' persistence.xml'? И какова ценность 'eclipselink.ddl-generation'? –

+0

Спасибо за помощь на этом Паскале. и мой ddl-gneration - это таблицы drop-and-create-tables, когда я возился с этим материалом. Как только я его отработаю, я просто прокомментирую это вообще. Удаление ссылочного имени столбца сейчас ... – digitaljoel

4

Я считаю, что этот вопрос является одним из чувствительности к регистру.

Вы не установили @Column в атрибуте идентификатора ключа, поэтому имя столбца по умолчанию - «КЛЮЧ». В своем @ManyToOne вы ссылаетесь на «ключ», который не является тем же столбцом, поэтому EclipseLink (который чувствителен к регистру и поддерживает ссылки на внешние ссылки без Id) предположил, что это был другой столбец, и тот, о котором он не знал, поэтому дал ему тип по умолчанию VARCHAR.

Либо измените имя referedColumnName на «KEY» или удалите его, как это не требуется при ссылке на одноточечный идентификатор.

Было бы полезно зарегистрировать ошибку на EclipseLink, чтобы предупреждение регистрировалось, когда ссылка на столбец не найдена или имеет неправильный случай (возможно, даже автоматически переключается на случай). На самом деле мы можем уже регистрировать предупреждение, вы можете проверить свой журнал.

+0

Ahhh, имеет смысл. Я не знал, что Эл был чувствительным к регистру. Спасибо за то, что он пролил свет на это. –

Смежные вопросы