Spring使用额外的字段来休眠ManyToMany

时间:2016-02-18 17:56:13

标签: java spring hibernate

我正在开发一个连接ManyToMany的驱动程序和许可证的演示项目。驱动程序可以拥有更多许可证,一个许可证可以连接到更多驱动程序这不是驾驶执照。我所说的许可证与他们可以或不能运输的货物有关。这是应该的方式。 最近,我有一个请求在这个连接中添加两个额外的字段。驱动程序和许可证通过表Drivers_License连接ManyToMany。额外的文件属于Drivers_License,即expirationDate和stateIssued。

现在这是我的数据库外观。

Driver                          Driver_License                   License
-----------                     -------------------             --------------------
driverID                         driverID                         licenseID
driverName                       licenseID                        licenseName
driverNumber                     expirationDate    
driverDateOfBirth                stateIssued

问题是我需要打破ManyToMany连接并创建两个OneToMany连接。我还需要使用driverID和licenseID创建复合键。

这就是我所说的例子。 Hibernate Many-to-Many Association with Extra Columns in Join Table Example

你能告诉我是否有一些完整的例子如何使用spring和hibernate来完成它,或者你知道一些可以通过经典方式使用ManyToMany来处理这个问题的例子吗?

2 个答案:

答案 0 :(得分:1)

只要您自己创建架构,就不需要将字段添加到join table。只需将它们添加到您的许可证Entity即可。这将是您似乎想要做的事情的近似值。

@Entity
public class Driver {    
    @Id @GeneratedValue private Integer id;
    @OneToMany private List<License> licenses;
    ... Driver Name, Number, & DateOfBirth ...
}

@Entity
public class License {    
    @Id @GeneratedValue private Integer id;
    private String licenseName;
    // add your fields here.
    @Temporal(TemporalType.DATE)
    private Date expirationDate;
    private String issueState;
}

同样,您不想弄乱join table,它们通常由持久性提供程序自动创建。

licenses表中的Driver列表将引用一个join table,它将为一个驱动程序保留许多许可证,因此OneToMany关系。

编辑:如果你有一个特定的许可证,并想知道它属于哪个驱动程序,比如因为你的名字查找了它,那么你应该将一个引用添加回驱动程序:

@ManyToOne
private Driver driver;

它将是ManyToOne,因为您将拥有许多引用One驱动程序的许可证。此关系将使用与Join Table中的licenses列表使用的Driver相同的Driver。这也会创建一个循环引用,License引用LicenseDriver引用Licenses。您必须先创建Driver,保存它们,创建merge,添加许可,保存,然后DriverLicense添加到 for(License license: licenses) { em.persist(license); } Driver driver = new Driver(); driver.getLicenses().add(licenses); em.persist(driver); // merge circular dependency for(License license: licenses) { license.setDriver(driver); em.merge(license); }

SQL

良好的建议:您应该打开{{1}}输出并稍微使用应用程序,以了解它可以做什么以及如何做。看到一切都在行动将有助于您更好地了解其工作原理。我通常使用创建,打印,删除等按钮创建一个简单的网页,并观察调试输出。

答案 1 :(得分:0)

确定。就像我在这里承诺的那样是我的解决方案Nicolas帮助我解决了我的实体组织中的一些问题,等等。

对于我的特殊问题,我选择了这个:http://www.codejava.net/frameworks/hibernate/hibernate-many-to-many-association-with-extra-columns-in-join-table-example

这解决了使用hibernate的问题。我也用DTO来重新包装咖啡豆。这个例子有一个错误,那就是他们在复合ID创建中没有使用LAZY。这就是为什么这个例子有无限循环问题。

这是我的代码解决了这个问题。

驱动程序实体

@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.driver", cascade = CascadeType.ALL)

 private List<DriverLicense> driverLicense = new ArrayList<DriverLicense>();

 public List<DriverLicense> getDriverLicense() {
   return driverLicense;

 public void setDriverLicense(List<DriverLicense> driverLicense) {
   this.driverLicense = driverLicense;
 }

DriverLicenseID(我的复合键)

@Embeddable
public class DriverLicenseID implements Serializable { 

    private static final long serialVersionUID = 1L;

    @ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL) 
    @JoinColumn(name="driverID")
    private Driver driver;

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    @ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
    private License license;

    public License getLicense() {
        return license;
    }

    public void setLicense(License license) {
        this.license = license;
    } 
}

许可实体

@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.license", cascade = CascadeType.ALL)

    private List<DriverLicense> driverLicense = new ArrayList<DriverLicense>();

    public List<DriverLicense> getDriverLicense() {
         return driverLicense;
    }

    public void setDriverLicense(List<DriverLicense> driverLicense) {
         this.driverLicense = driverLicense;
    }

谢谢尼克!您帮助我理解了Entity的概念等等。风格全新。