2

我正在尝试使用实体和 JPA 创建树。我有一个具有以下属性的类。

public class Dir
{

@Id
@Basic(optional = false)
@NotNull
@Column(name = "dirId")
private Integer dirId;

@OneToOne(mappedBy="dirId", cascade= CascadeType.ALL)
private Dir parent;
...

一个节点知道它的父节点是谁,如果它没有父节点,它就是根节点。这就是我可以轻松构建一棵树的方法。但是......我认为映射对于这个想法是不正确的。尝试部署时出现以下错误:

An incompatible mapping has been encountered between [class com.dv.oa.model.entity.dir.Dir] and [class com.dv.oa.model.entity.dir.Dir]. This usually occurs when the cardinality of a mapping does not correspond with the cardinality of its backpointer.

它谈到了基数。但这没有意义,一个节点只能有一个父节点。这就是我选择的原因@OneToOne

任何人都可以对此有所了解吗?我想另一种问这个问题的方法是,你如何将一个实体映射到它自己的另一个实例?

编辑

这是我的表结构:

mysql> describe dir;
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| dirId        | int(11)      | NO   | PRI | NULL    |       |
| DTYPE        | varchar(31)  | YES  |     | NULL    |       |
| dirName      | varchar(255) | YES  |     | NULL    |       |
| companyOwner | int(11)      | YES  | MUL | NULL    |       |
| userOwner    | int(11)      | YES  | MUL | NULL    |       |
| parent       | int(11)      | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
4

3 回答 3

5

You're pointing to the wrong column for the owning side of the mapping. Also your relationship is not OneToOne because a single Parent can have many Children.

@Entity
public class Dir
{

  //This field is a table column
  //It uniquely identifies a row on the DIR table
  @Id
  private int dirId;

  //This field is a table column
  // It identifies the parent of the current row
  // It it will be written as the type of dirId
  // By default this relationship will be eagerly fetched
  // , which you may or may not want
  @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE})
  private Dir parent;

  //This field is not a table column
  // It is a collection of those Dir rows that have this row as a parent. 
  // This is the other side of the relationship defined by the parent field.
  @OneToMany(mappedBy="parent")
  private Set<Dir> children;
}
于 2013-01-17T21:14:51.823 回答
2

问题似乎是属性mappedBy,尝试将其删除。我认为您不需要使用类似的东西来实现。

@Entity
public class Dir {

@Id
@Basic(optional = false)
@NotNull
@Column(name = "dirId")
private Integer dirId;

@OneToOne(cascade=CascadeType.ALL )
private Dir parent;

    ....

}
于 2013-01-17T21:06:46.113 回答
-2

您应该执行Composite Pattern。使用 JPA 很简单:

  • 创建一个抽象基类,例如 FileSystemItem。
  • 创建一个名为 Folder 的类和一个名为 File 的类,它们都扩展了 Node.js。
  • 选择继承策略。为此,您可能会使用鉴别器并将两种类型都放在一个文件中。
  • 将属性名称放在基类中。
  • 在文件夹类中创建一个集合,而不是 Files,而是 FileSystemItems。

差不多就是这样。另一个重大决定是如何处理 add 方法。如果你把它放在基类中,如果有人在 File 上调用它,你必须抛出一个不受支持的操作异常。

于 2013-01-17T21:22:53.933 回答