【问题标题】:Hibernate MS SQL Join issue休眠 MS SQL 加入问题
【发布时间】:2010-02-20 11:50:43
【问题描述】:

我在客户端 mssql 数据库中有两个表。第一个是工作表 - 所以我创建了一个包含负载类型和负载重量以及所有这些东西的工作实体 - 工作正常。

我现在的问题是有第二个表,其中包含有关装载和卸载点的信息。第二个表,我称之为 JEP,有一个主键,由几项组成:类型(加载或卸载)、邮政编码和客户编号。

我创建了一个实体 JobEndPoint,NetBeans 还创建了一个对象,表示包含所有这些字段的主键 JobEndPointPK。

我想向我的 Job 实体添加两个 JobEndPoint(loadPoint 和 unloadPoint)。我现在的问题是:如何在 Hibernate 中注释它?在我看来,这是一个@OneToOne 关系船。如果我能指定一个像SELECT * FROM JEP WHERE type="load" AND customer_nr="123" AND zip_code="123 ..."这样的SELECT语句就完美了。Hibernate可以做到吗?

感谢您的帮助!

问候,

马可


这里是实体:

@Entity
@Table(name = "Auftragsdaten", catalog = "...", schema = "dbo")
public class Job implements Comparable<Object>, Serializable {

    private static final long serialVersionUID = 4285871251915951149L;

    @Id
    @Basic(optional = false)
    @Column(name = "`id`", nullable = false)
    int id;

    @Column(name = "`AufNr`", nullable=false)
    int jobId;

    @Transient
    List<Integer> jobsAdded;

    @Column(name = "`Beladedatum`", nullable=false)
    @Temporal(TemporalType.DATE)
    Date loadDate;

    @Column(name = "`Beladezeit`")
    @Temporal(TemporalType.TIME)
    Date loadTimeFrom;

    @Transient
    Date loadTimeTo;

    @Column(name = "`Entladedatum`", nullable=false)
    @Temporal(TemporalType.DATE)
    Date unloadDate;

    @Column(name = "`Entladezeit Beginn`")
    @Temporal(TemporalType.TIME)
    Date unloadTimeFrom;

    @Column(name = "`Entladezeit Ende`")
    @Temporal(TemporalType.TIME)
    Date unloadTimeTo;

    @Transient
    List<JobEndPoint> froms;

    @OneToOne
    @JoinColumns ({
        @JoinColumn(name="`Beladetyp`", referencedColumnName = "`Ladetyp`", insertable = false, updatable = false),
        @JoinColumn(name="`AbsNr`", referencedColumnName = "`KundenNr`", insertable = false, updatable = false),
        @JoinColumn(name="`Verkehrsart`", referencedColumnName = "`VerkArt`", insertable = false, updatable = false),
        @JoinColumn(name="`von LKZ`", referencedColumnName = "`LKZ`", insertable = false, updatable = false),
        @JoinColumn(name="`von PLZ`", referencedColumnName = "`PLZ`", insertable = false, updatable = false)
    })
    JobEndPoint fromPoint;

    @Transient
    JobEndPoint toPoint;

    @Column(name = "`Verkehrsart`", length = 10, nullable=false)
    @Enumerated
    JobType type;

    @Column(name = "`Anzahl Paletten CCG1`")
    int numberCCG1;

    @Column(name = "`Anzahl Paletten CCG2`")
    int numberCCG2;

    @Transient
    int numberFullContainer;

    @Transient
    int numberEmptyContainer;

    @Column(name = "`Anzahl Container`")
    int numberContainer;

    @Column(name = "`Anz Stellplätze`")
    int numberUnits;

    @Column(name = "`Bruttogewicht`", nullable=false)
    int loadWeight;

    @ManyToOne
    @JoinColumn(name="`Kühlkennzeichen`")
    CoolingCode coolingCode;
}

@Entity
@Table(name = "BES", catalog = "...", schema = "dbo")
public class JobEndPoint implements Serializable {

    private static final long serialVersionUID = 1017986852824783744L;

    @Id
    protected JobEndPointPK jobEndPointPK;

    (...)
}

@Embeddable
public class JobEndPointPK implements Serializable {

    @Basic(optional = false)
    @Column(name = "`Ladetyp`", nullable = false, length = 50)
    @Enumerated
    EndPointType type;

    @Basic(optional = false)
    @Column(name = "`KundenNr`", nullable = false)
    int customerId;

    @Basic(optional = false)
    @Column(name = "`VerkArt`", nullable = false, length = 10)
    @Enumerated
    JobType jobType;

    @Basic(optional = false)
    @Column(name = "`LKZ`", nullable = false, length = 3)
    String countryCode;

    @Basic(optional = false)
    @Column(name = "`PLZ`", nullable = false, length = 7)
    String zipCode;
}

【问题讨论】:

    标签: java sql-server hibernate left-join table-relationships


    【解决方案1】:

    一般来说,我建议使用生成的内部主键而不是复合键。但是,如果您需要坚持使用复合键,这里有一些想法可能会有所帮助。

    我了解JobEndPointPK 是作为标识符组件实现的(请参阅 Hibernate 参考,chapter 8.4)。注意:正确实现equals 和 hashCode` 方法至关重要,因为 Hibernate 依赖于这些方法。

    更新:前提是您的 JobEndPointJobEndPointPK 看起来像这样:

    @Embeddable
    class JobEndPointPK {
        @Column(name = "type", nullable = false)
        @Enumerated
        EndPointType type;
    
        @Column(name = "zipCode", nullable = false)
        String zipCode;
    
        @Column(name = "customerNumber", nullable = false)
        int customerId;
    
        // equals, hasCode, getters, setters etc.
    }
    
    @Entity
    class JobEndPoint {
        @Id
        private JobEndPointPK key;
    
        // getters, setters etc.
    }
    

    映射注释类似于:

    @Entity
    class Job {
        @OneToOne
        @JoinColumns ({
            @JoinColumn(name="loadPointType", referencedColumnName = "type"),
            @JoinColumn(name="loadPointZip", referencedColumnName = "zipCode"),
            @JoinColumn(name="loadPointCust", referencedColumnName = "customerNumber")
        })
        private JobEndPoint loadPoint;
        // similarly for unloadPoint
        // other properties
    }
    

    示例改编自here

    我不确定如何处理JobEndPointPK.type,至于loadPoint,显然是Load,对于unloadPointUnload,所以你很可能不想将它单独存储在数据库。我的猜测是您可以使用 @Formula 注释指定值,但我还没有看到任何具体示例。

    请注意,所有这些代码都是纯实验性的,我没有测试过。

    主题还有其他变体。更多详细信息,请参阅Chapter 8 of Java Persistence with Hibernate 中的“带注释的复合键”部分。

    【讨论】:

    • 谢谢!这看起来像是一个开始。尽管我想要 JobEndPoint 对象,但我在 Job 对象中有 JobEndPointPK 是否正确?或者另一种方式:如何在运行时将 JobEndPointPK 存储在 Job 中的 JobEndPoint 对象?
    • @Marco 该死的,我搞砸了 :-( 现在我更新了代码。我还链接了一个更好的例子。
    • 你好。谢谢你一直陪着我。我在上面发布了我的实体声明,希望它会有所帮助......
    • 如果你省略了条件 loadtype (first @JoinColumn) Hibernate 报告:Caused by: org.hibernate.AnnotationException: referencedColumnNames(KundenNr, VerkArt, LKZ, PLZ) Job.fromPoint 引用 JobEndPoint 未映射到单个属性
    • @Marco 现在我对你的问题到底是什么感到困惑。您的代码中确实有@JoinColumn(name="``von LKZ``", referencedColumnName = "``LKZ``", ...),,这应该进行过滤吗?你的表中有LKZ 列吗?如果有,是否映射到JobEndPointPK
    猜你喜欢
    • 2014-07-26
    • 2010-10-14
    • 2017-01-10
    • 2015-03-21
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多