java - 为什么 JPA 无论键类型如何都为 JoinColumn 选择 String?

标签 java postgresql jpa eclipselink jpa-2.0

使用EclipseLink JPA2实现(不确定是否与Hibernate实现相同)

我有一个简单的结构,组织实体有契约(Contract)。这是我从 postgres 导出的用于创建组织的 sql

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

如果我像这样指定组织的契约(Contract)方:

@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) 字段来引用组织 key ,这对我来说没有意义。我知道我可以按如下方式使用 columnDefinition:

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

获取bigint类型而不是字符类型。

我期望它获得正确的列类型是不现实的吗?是我用错了,还是我有错误的期望?难道我每次都必须使用 columnDefinition 吗?

更新: 这是组织实体的相关信息

@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        
 }

这是 Contract 实体

@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
}

最佳答案

我认为问题是区分大小写。

您没有在键 id 属性上设置 @Column,因此默认列名是“KEY”。 在您的@ManyToOne 中,您引用了“key”,它不是同一列,因此 EclipseLink(区分大小写并支持非 Id 外键引用)假设这是一个不同的列,并且它不知道,所以给了它是 VARCHAR 的默认类型。

将 referencedColumnName 更改为“KEY”或删除它,因为在引用单例 ID 时不需要它。

在 EclipseLink 上记录一个错误是值得的,当列引用未找到或大小写错误(甚至可能自动切换大小写)时应记录警告。实际上我们可能已经在记录警告,您可能希望检查您的日志。

关于java - 为什么 JPA 无论键类型如何都为 JoinColumn 选择 String?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4005984/

相关文章:

java - 找不到适合模式的正则表达式

postgresql - 在 Libreoffice Base 中用下拉列表替换数字外键

postgresql - 将逻辑模型转换为物理模型。难以理解 ERD

java - 无法在 hibernate 状态下保存实体

java - Hibernate 3.6.10 不通过 OneToMany JoinTable 级联删除

java - 如何修复: javax. persistence.TransactionRequiredException?

java - 通过 Java 播放实时流音频

java - 如何通过管道传输 JVM 堆转储

java - 为 Fragment 中的对象赋值时出现问题

database - 即使更新的列不是索引列,postgresql 也会更新索引吗?