休止状態の関係に問題があります。n:m休止状態の追加情報との関係
シナリオ:2つのエンティティのタスクとリソースがあります。すべての「タスク」は複数の「リソース」を持つことができ、すべての「リソース」は複数の「タスク」を持つことができます。関係がn:m-関係であるように。リレーションテーブルでは、 'リソース'のタイプに対して追加の列が必要です。なぜなら、 'リソース'が持つことができる 'タスク'には異なる役割があるからです。
余計な列を持つ結合テーブルの例がいくつか見つかり、そのように実装しようとしました。例:http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
問題: 「リソース」との関連付けを持つ「タスク」を削除すると、javax.persistence.EntityNotFoundException:削除されたエンティティがpersist:[...]にスローされます。
私の質問 このシナリオを処理する最善の方法は、「余分な列を持つテーブルを結合する」ですか?または、 'リソース'が持つことができるすべての役割に対して、単純なManyToMany(@JoinTable)関係を使用する方が良いでしょうか?
例:4つの役割がある場合、「タスク」と「リソース」の間に4つの異なるリレーション表があります。
次のような理由が考えられますか?
‘javax.persistence.EntityNotFoundException: deleted entity passed to persist: […]’
編集:
ここdeleted entity passed to persist: [com.domain.Task# ]
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1369)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)
org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81)
org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy43.deleteVorgaenge(Unknown Source)
com.service.locklayers.TaskLockService.deleteTasks(TaskLockService.java:364)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:303)
sun.rmi.transport.Transport$1.run(Transport.java:159)
java.security.AccessController.doPrivileged(Native Method)
sun.rmi.transport.Transport.serviceCall(Transport.java:155)
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:662)
関与のクラスがある...
@Entity
@Table(name = "task")
public class Task implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "task_id")
private int taskId;
private String name;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "taskFk", cascade = CascadeType.ALL)
Set<TaskZuResource> taskZuResourceList = new HashSet<TaskZuResource>();
public int getId()
{
return taskId;
}
}
@Entity
@Table(name = "resource")
public class Resource implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "resource_id")
private int resourceId;
private String name;
@OneToMany(mappedBy = "resourceFk", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
Set<TaskZuResource> taskZuResourceList = new HashSet<TaskZuResource>();
public int getId()
{
return resourceId;
}
}
@Entity
@Table(name = "task_zu_resource")
public class TaskZuResource implements Serializable
{
@EmbeddedId
private TaskZuResourceId pk;
@MapsId("taskFk")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "task_fk")
private Task taskFk;
@MapsId("resourceFk")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "resource_fk")
private Resource resourceFk;
public TaskZuResource()
{
}
public TaskZuResource(Task taskFk, Resource resourceFk, int resourcenArt)
{
this.taskFk = taskFk;
this.resourceFk = resourceFk;
pk = new TaskZuResourceId(taskFk.getId(), resourceFk.getId(), resourcenArt);
}
public TaskZuResourceId getPk()
{
return pk;
}
public void setPk(TaskZuResourceId pk)
{
this.pk = pk;
}
public Task getTaskFk()
{
return taskFk;
}
public void setTaskFk(Task taskFk)
{
this.taskFk = taskFk;
}
public Resource getResourceFk()
{
return resourceFk;
}
public void setResourceFk(Resource resourceFk)
{
this.resourceFk = resourceFk;
}
@Transient
public int getResourcenType()
{
return getPk().getResourcenType();
}
public void setResourcenType(int resourcenArt)
{
getPk().setResourcenType(resourcenArt);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((pk == null) ? 0 : pk.hashCode());
result = prime * result + ((resourceFk == null) ? 0 : resourceFk.hashCode());
result = prime * result + ((taskFk == null) ? 0 : taskFk.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TaskZuResource other = (TaskZuResource) obj;
if (pk == null)
{
if (other.pk != null)
return false;
}
else
if (!pk.equals(other.pk))
return false;
if (resourceFk == null)
{
if (other.resourceFk != null)
return false;
}
else
if (!resourceFk.equals(other.resourceFk))
return false;
if (taskFk == null)
{
if (other.taskFk != null)
return false;
}
else
if (!taskFk.equals(other.taskFk))
return false;
return true;
}
}
@Embeddable
public class TaskZuResourceId implements Serializable
{
private int taskFk;
private int resourceFk;
@Column(name = "resourcen_type")
private int resourcenType;
public TaskZuResourceId()
{
}
public TaskZuResourceId(int taskFk, int resourceFk, int resourcenType)
{
this.taskFk = taskFk;
this.resourceFk = resourceFk;
this.resourcenType = resourcenType;
}
public int getTaskFk()
{
return taskFk;
}
public void setTaskFk(int taskFk)
{
this.taskFk = taskFk;
}
public int getResourceFk()
{
return resourceFk;
}
public void setResourceFk(int resourceFk)
{
this.resourceFk = resourceFk;
}
public int getResourcenType()
{
return resourcenType;
}
public void setResourcenType(int resourcenType)
{
this.resourcenType = resourcenType;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + resourceFk;
result = prime * result + resourcenType;
result = prime * result + taskFk;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TaskZuResourceId other = (TaskZuResourceId) obj;
if (resourceFk != other.resourceFk)
return false;
if (resourcenType != other.resourcenType)
return false;
if (taskFk != other.taskFk)
return false;
return true;
}
}
Thxを
エンティティ、この例外をスローするコード、および例外の完全なスタックトレースを表示します。 –
希望のクラスは – Seffel
です。タスクを削除すると、リソースも削除する必要がありますか? –