Как настроить отношения "многие ко многим" в режиме гибернации, используя сопоставление XML
У меня следующая ситуация:
Я новичок в спящем режиме, и у меня есть проект, который нужно завершить в ближайшие дни.
Речь идет о веб-приложении CRUD на Java. Первые шаги выполнены, но я действительно застрял и не могу найти в интернете никакой помощи по поводу следующей ситуации:
У меня есть таблица проекта, которая может иметь много действий из таблицы действий. (Отношение ко многим ко многим).
У меня также есть таблица платежей, которая имеет первичный ключ, (paymentId
) и 2 внешних ключа Project и action ( projectId,actionId), а также некоторые другие поля, такие как paymentMethod
, price
, startDate
, endDate
, Я на самом деле использую таблицу платежей, чтобы связать каждый проект с каждым действием, добавив некоторую дополнительную информацию, такую как сумма и т.
Надеюсь, я проясню свои мысли по поводу общего вида.
Я не знаю, как я должен сделать файлы сопоставления? Нужно ли создавать 2 файла сопоставления или 3? (Project.hbm.xml
, action.hbm.xml
а также payments.hbm.xml
)
Вначале я думал, что разделить отношения на следующие:
класс POJO проекта, который будет иметь отношение один-ко-многим с платежами (и XML-сопоставление будет иметь отношение "один-ко-многим" 1), и класс POJO действия, чтобы иметь много-к-одному с платежами (также с соответствующим файлом сопоставления XML),
А также иметь класс POJO с платежами, в том числе Objects Action и Projects, и связанными между собой связями в файлах XML.
Я не видел такой реализации ни в одном учебнике, ни на каком-либо сайте, я не знаю, нормально ли это?
Единственное, что я нашел, было отношение "многие ко многим" с использованием аннотации (в основном) и наличием таблицы промежуточных шагов (платежи в моем случае) только с двумя внешними ключами без какого-либо первичного ключа и дополнительных полей, подобных этим, которые я хочу.
XML проекта:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.nisid.entities.Project" table="projects">
<meta attribute="class-description"> This class contains the project records. </meta>
<id name="projectId" type="int" column="projectId">
<generator class="native">
</generator>
</id>
<many-to-one name="fkCustomer" class="com.nisid.entities.Customers"
fetch="select">
<column name="customerId" not-null="true"/>
</many-to-one>
<set name="payments"
lazy="true" fetch="select" cascade="all">
<key>
<column name="projectId" />
</key>
<one-to-many class="com.nisid.entities.Payment" />
</set>
<property name="projectName" column="projectName" type="string"/>
<property name="projectDescription" column="description" type="string"/>
</class>
</hibernate-mapping>
Действие xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.nisid.entities.Action" table="actions" >
<id name="actionId" type="int">
<column name="actionId" />
<generator class="native" >
</generator>
</id>
<property name="actionName" type="string">
<column name="actionName" />
</property>
<set name="payments" inverse="true" lazy="true" fetch="select">
<key>
<column name="actionId" />
</key>
<one-to-many class="com.nisid.entities.Payment" />
</set>
</class>
</hibernate-mapping>
Оплата (отображение xml):
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.nisid.entities.Payment" table="payments">
<composite-id name="paymentId" class="com.nisid.entities.PaymentID" >
<key-property name="myproject" column="projectId" />
<key-property name="myaction" column="actionId" />
</composite-id>
<component name="myproject">
<many-to-one name="project" class="com.nisid.entities.Project"
>
<column name="projectId" not-null="true" />
</many-to-one>
</component>
<component name="myaction">
<many-to-one name="action" class="com.nisid.entities.Action"
>
<column name="actionId" not-null="true" />
</many-to-one>
</component>
<property name="amount" column="amount" type="int"/>
<property name="paymentDate" column="paymentDate" type="date"/>
<property name="paymentExpire" column="paymentExpire" type="date"/>
<property name="paymentMethod" column="paymentMethod" type="string"/>
</class>
И классы ppojo:
Действие:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.nisid.entities;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
*
* @author p293
*/
public class Action {
private int actionId;
private String actionName;
private Set payments=new HashSet();
public Action(){}
public Action(String actionName) {
this.actionName = actionName;
}
public int getActionId() {
return actionId;
}
public void setActionId(int actionId) {
this.actionId = actionId;
}
public String getActionName() {
return actionName;
}
public void setActionName(String actionName) {
this.actionName = actionName;
}
public Set getPayments() {
return payments;
}
public void setPayments(Set payments) {
this.payments = payments;
}
@Override
public int hashCode() {
int hash = 5;
hash = 89 * hash + Objects.hashCode(this.actionName);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Action other = (Action) obj;
if (!Objects.equals(this.actionName, other.actionName)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Action{" + "=" + actionName + '}';
}
}
Проект:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.nisid.entities;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
*
* @author p293
*/
public class Project {
private int projectId;
private String projectName;
private String projectDescription;
private Customers fkCustomer;
private Set payments=new HashSet();
public Project(){
}
public Project( String projectName, String projectDescription) {
this.projectName = projectName;
this.projectDescription = projectDescription;
}
public int getProjectId() {
return projectId;
}
public void setProjectId(int projectId) {
this.projectId = projectId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getProjectDescription() {
return projectDescription;
}
public void setProjectDescription(String projectDescription) {
this.projectDescription = projectDescription;
}
public Customers getFkCustomer() {
return fkCustomer;
}
public void setFkCustomer(Customers fkCustomer) {
this.fkCustomer = fkCustomer;
}
public Set getPayments() {
return payments;
}
public void setPayments(Set payments) {
this.payments = payments;
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + Objects.hashCode(this.projectName);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Project other = (Project) obj;
if (!Objects.equals(this.projectName, other.projectName)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Project{" + "projectName=" + projectName + ",with description=" + projectDescription + '}';
}
}
Оплата:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.nisid.entities;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
*
* @author p293
*/
public class Payment {
private PaymentID paymentId=new PaymentID();
private int amount;
private Date paymentDate;
private Date paymentExpire;
private String paymentMethod;
public Payment(int fkProjectId, int fkActionId, int amount, Date paymentDate, Date paymentExpire, String paymentMethod) {
this.amount = amount;
this.paymentDate = paymentDate;
this.paymentExpire = paymentExpire;
this.paymentMethod=paymentMethod;
}
public Payment(){}
public PaymentID getPaymentId() {
return paymentId;
}
public void setPaymentId(PaymentID paymentId) {
this.paymentId = paymentId;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public Date getPaymentDate() {
return paymentDate;
}
public void setPaymentDate(Date paymentDate) {
this.paymentDate = paymentDate;
}
public Date getPaymentExpire() {
return paymentExpire;
}
public void setPaymentExpire(Date paymentExpire) {
this.paymentExpire = paymentExpire;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public Project getProject(){
return getPaymentId().getProject();
}
public Action getAction(){
return getPaymentId().getAction();
}
public void setAction(Action action){
getPaymentId().setAction(action);
}
public void setProject(Project project){
getPaymentId().setProject(project);
}
@Override
public int hashCode() {
int hash = 3;
hash = 89 * hash + this.amount;
hash = 89 * hash + Objects.hashCode(this.paymentMethod);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Payment other = (Payment) obj;
if (this.amount != other.amount) {
return false;
}
if (!Objects.equals(this.paymentMethod, other.paymentMethod)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Payment{" + "amount=" + amount + ", paymentMethod=" + paymentMethod + '}';
}
}
PaymentID:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.nisid.entities;
import java.util.Objects;
/**
*
* @author lurtzaki
*/
public class PaymentID {
private Project myproject;
private Action myaction ;
public PaymentID(){
super();}
public Project getProject() {
return myproject;
}
public void setProject(Project project) {
this.myproject = project;
}
public Action getAction() {
return myaction;
}
public void setAction(Action action) {
this.myaction = action;
}
@Override
public int hashCode() {
int hash = 3;
hash = 17 * hash + Objects.hashCode(this.myproject);
hash = 17 * hash + Objects.hashCode(this.myaction);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PaymentID other = (PaymentID) obj;
if (!Objects.equals(this.myproject, other.myproject)) {
return false;
}
if (!Objects.equals(this.myaction, other.myaction)) {
return false;
}
return true;
}
}
Новый XML:
<composite-id name="paymentId" class="com.nisid.entities.PaymentID">
<key-many-to-one name="myproject" class="com.nisid.entities.Project">
<column name="projectId"/>
</key-many-to-one>
<key-many-to-one name="myaction" class="com.nisid.entities.Action">
<column name="actionId" />
</key-many-to-one>
</composite-id>
<property name="amount" column="amount" type="int"/>
<property name="paymentDate" column="paymentDate" type="date"/>
<property name="paymentExpire" column="paymentExpire" type="date"/>
<property name="paymentMethod" column="paymentMethod" type="string"/>
1 ответ
Если тебе надо paymentMethod
, price
, startDate
, endDate
в таблице платежей вам необходимо сопоставить 3 объекта. Вы можете отобразить действие и проецировать многие ко многим друг другу, используя таблицу платежей в качестве своей join table
, или если у вас есть проблемы с поиском, например, many to many
с join table
Вы также можете использовать многие к одному для каждого действия таблицы и проекта, чтобы табе платежа.
редактировать:
попробуйте сначала протестировать проект и оплату, удалите другую потенциальную ошибку, если вам это удастся, вы можете внедрить ее в другую таблицу. Я думаю, что отношение xml будет таким:
в project.hbm.xml
изменить один-ко-многим стало так:
<list name="payments"
inverse="true"
cascade="save-update">
<key column="projectId"/>
<index column="actionId"/>
<one-to-many class="Payment"/>
</list>
в action.hbm.xml
изменить один-ко-многим стало так:
<list name="payments"
inverse="true"
cascade="save-update">
<key column="actionId"/>
<index column="projectId"/>
<one-to-many class="Payment"/>
</list>
и в payments.hbm.xml
как это (мне то, что вам не нужно <component>
тег там):
<hibernate-mapping>
<class name="com.nisid.entities.Payment" table="payments">
<composite-id name="paymentId" class="com.nisid.entities.PaymentID" >
<key-property name="myproject" column="projectId" />
<key-property name="myaction" column="actionId" />
</composite-id>
<many-to-one name="project" column="projectId" insert="false" update="false" not-null="true"/>
<many-to-one name="action" column="actionId" insert="false" update="false" not-null="true"/>
<property name="amount" column="amount" type="int"/>
<property name="paymentDate" column="paymentDate" type="date"/>
<property name="paymentExpire" column="paymentExpire" type="date"/>
<property name="paymentMethod" column="paymentMethod" type="string"/>
</class>