简体   繁体   English

Hibernate MS SQL Join问题

[英]Hibernate MS SQL Join issue

I have two tables in the clients mssql database. 我在客户端mssql数据库中有两个表。 The first is a job table - so I created an Job entity which contains the load type and load weight and all that stuff - works fine. 第一个是作业表-所以我创建了一个Job实体,其中包含负载类型和负载重量以及所有这些东西-正常工作。

My problem now is that there is a second table that includes informations about the load and unload point. 我现在的问题是,还有第二个表,其中包含有关加载和卸载点的信息。 The second table, I call it JEP, has a primary key consisting of several items: the type (load or unload), the zip code and the customer number. 第二张表,我称它为JEP,具有一个由几项组成的主键:类型(加载或卸载),邮政编码和客户编号。

I created an entity JobEndPoint and NetBeans also created an object representing the primary key JobEndPointPK containing all that fields. 我创建了一个实体JobEndPoint,NetBeans也创建了一个对象,该对象表示包含所有字段的主键JobEndPointPK。

I want to add two JobEndPoint (loadPoint and unloadPoint) to my Job entity. 我想向我的Job实体添加两个JobEndPoint(loadPoint和unloadPoint)。 My problem is now: how do I annotate that in Hibernate? 现在的问题是:如何在Hibernate中对此进行注释? In my opinion it is an @OneToOne relation ship. 我认为这是@OneToOne关系船。 It would be perfect if I could specify a SELECT statement like SELECT * FROM JEP WHERE type="load" AND customer_nr="123" AND zip_code="123 ...". 如果可以指定SELECT * FROM JEP WHERE type="load" AND customer_nr="123" AND zip_code="123 ...”这样的SELECT语句,那将是完美的。 Is that possible with Hibernate? Hibernate有可能吗?

Thanks for your help! 谢谢你的帮助!

Regeards, 混蛋,

Marco 马可


Here are the Entities: 这是实体:

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

In general, I would recommend using a generated internal primary key instead of the composite key. 通常,我建议使用生成的内部主键而不是组合键。 However, if you need to stick with your composite key, here are some ideas that hopefully help. 但是,如果您需要坚持使用复合键,则可以从中获得一些帮助。

I understand that JobEndPointPK is implemented as an identifier component (see the Hibernate Reference, chapter 8.4 ). 我知道JobEndPointPK是作为标识符组件实现的(请参见Hibernate Reference, 第8.4章 )。 Note: it is critical that it implements the equals and hashCode` methods correctly, as Hibernate relies on these. 注意:至关重要的是,它正确地实现equals和hashCode`方法,因为Hibernate依赖于这些方法。

Updated: Provided that your JobEndPoint and JobEndPointPK looks something like this: 更新:如果您的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.
}

The mapping annotation would be something like: 映射注释将类似于:

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

The example is adapted from here . 该示例从此处改编。

I am not sure how to deal with JobEndPointPK.type though, as for loadPoint it is obviously Load and for unloadPoint , Unload , so you most probably don't want to store it separately in the DB. 我不确定如何处理JobEndPointPK.type ,因为对于loadPoint来说显然是Load ,对于unloadPoint来说是Unload ,所以您很可能不想将其单独存储在数据库中。 My gues is that you can specify the value with the @Formula annotation, but I haven't seen any concrete example for this. 我的@Formula是,您可以使用@Formula批注指定值,但是我还没有看到任何具体的示例。

Note that all this code is purely experimental, I haven't tested it. 请注意,所有这些代码都是纯实验性的,我尚未对其进行测试。

There are other variations on the theme. 主题还有其他变化。 For more details, see the section "Composite keys with annotations" in Chapter 8 of Java Persistence with Hibernate . 有关更多详细信息,请参见《 Java Persistence with Hibernate第8章中的 “带注释的复合键”部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM