Hibernate通过在ManyToMany关联上将完全限定的类名添加到属性名而失败 [英] Hibernate failing by prepending fully qualified class name to property name on ManyToMany association
问题描述
我正在尝试使用 ManyToMany
关联将两个对象相互映射,但是由于某些原因,当我使用mapledBy属性时,休眠似乎对我正在映射的对象感到困惑.关于我的映射,唯一奇怪的是,关联不是在其中一个条目的主键字段上进行的(尽管该字段是唯一的).
I'm trying to map two objects to each other using a ManyToMany
association, but for some reason when I use the mappedBy property, hibernate seems to be getting confused about exactly what I am mapping. The only odd thing about my mapping here is that the association is not done on a primary key field in one of the entries (the field is unique though).
这些表是:
Sequence (
id NUMBER,
reference VARCHAR,
)
Project (
id NUMBER
)
Sequence_Project (
proj_id number references Project(id),
reference varchar references Sequence(reference)
)
对象看起来像(注释在getter上,将它们放在字段上以进行压缩):
The objects look like (annotations are on the getter, put them on fields to condense a bit):
class Sequence {
@Id
private int id;
private String reference;
@ManyToMany(mappedBy="sequences")
private List<Project> projects;
}
以及拥有方:
class Project {
@Id
private int id;
@ManyToMany
@JoinTable(name="sequence_project",
joinColumns=@JoinColumn(name="id"),
inverseJoinColumns=@JoinColumn(name="reference",
referencedColumnName="reference"))
private List<Sequence> sequences;
}
此操作失败,并出现MappingException:
This fails with a MappingException:
在实体[test.local.entities.Project]上找不到属性参考[_test_local_entities_Project_sequences]
property-ref [_test_local_entities_Project_sequences] not found on entity [test.local.entities.Project]
似乎奇怪的是在全限定的类名前加上下划线.如何避免这种情况发生?
It seems to weirdly prepend the fully qualified class name, divided by underscores. How can I avoid this from happening?
我还玩了一点.更改mapledBy属性的名称会引发不同的异常,即:
I played around with this a bit more. Changing the name of the mappedBy property throws a different exception, namely:
org.hibernate.AnnotationException:mappedBy通过引用未知目标实体属性:test.local.entities.Project.sequences
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: test.local.entities.Project.sequences
因此注释正在正确处理,但是由于某种原因,属性引用未正确添加到Hibernate的内部配置中.
So the annotation is processing correctly, but somehow the property reference isn't correctly added to Hibernate's internal configuration.
推荐答案
我已经完成了您的问题提出的相同方案.而且,正如预期的那样,我得到了同样的例外.与补充任务一样,我也使用相同的方案,但通过使用非主键作为联接列来使用一对多的一对多 ,例如引用.我现在知道了
I have done the same scenario proposed by your question. And, as expected, i get the same exception. Just as complementary task, i have done the same scenario but with one-to-many many-to-one by using a non-primary key as joined column such as reference. I get now
SecondaryTable JoinColumn无法引用非主键
好吧,这可能是个错误吗???好吧,是的(您的解决方法工作正常(+1)).如果要使用非主键作为主键,则必须确保它是唯一的.也许可以解释为什么Hibernate不允许使用非主键作为主键(Unaware用户可能会发生意外行为).
Well, can it be a bug ??? Well, yes (and your workaround works fine (+1)). If you want to use a non-primary key as primary key, you must make sure it is unique. Maybe it explains why Hibernate does not allow to use non-primary key as primary key (Unaware users can get unexpected behaviors).
如果要使用相同的映射,可以将@ManyToMany关系拆分为@ OneToMany-ManyToOne 通过使用封装,您无需担心已加入的类
If you want to use the same mapping, You can split your @ManyToMany relationship into @OneToMany-ManyToOne By using encapsulation, you do not need to worry about your joined class
项目
@Entity
public class Project implements Serializable {
@Id
@GeneratedValue
private Integer id;
@OneToMany(mappedBy="project")
private List<ProjectSequence> projectSequenceList = new ArrayList<ProjectSequence>();
@Transient
private List<Sequence> sequenceList = null;
// getters and setters
public void addSequence(Sequence sequence) {
projectSequenceList.add(new ProjectSequence(new ProjectSequence.ProjectSequenceId(id, sequence.getReference())));
}
public List<Sequence> getSequenceList() {
if(sequenceList != null)
return sequenceList;
sequenceList = new ArrayList<Sequence>();
for (ProjectSequence projectSequence : projectSequenceList)
sequenceList.add(projectSequence.getSequence());
return sequenceList;
}
}
序列
@Entity
public class Sequence implements Serializable {
@Id
private Integer id;
private String reference;
@OneToMany(mappedBy="sequence")
private List<ProjectSequence> projectSequenceList = new ArrayList<ProjectSequence>();
@Transient
private List<Project> projectList = null;
// getters and setters
public void addProject(Project project) {
projectSequenceList.add(new ProjectSequence(new ProjectSequence.ProjectSequenceId(project.getId(), reference)));
}
public List<Project> getProjectList() {
if(projectList != null)
return projectList;
projectList = new ArrayList<Project>();
for (ProjectSequence projectSequence : projectSequenceList)
projectList.add(projectSequence.getProject());
return projectList;
}
}
ProjectSequence
@Entity
public class ProjectSequence {
@EmbeddedId
private ProjectSequenceId projectSequenceId;
@ManyToOne
@JoinColumn(name="ID", insertable=false, updatable=false)
private Project project;
@ManyToOne
@JoinColumn(name="REFERENCE", referencedColumnName="REFERENCE", insertable=false, updatable=false)
private Sequence sequence;
public ProjectSequence() {}
public ProjectSequence(ProjectSequenceId projectSequenceId) {
this.projectSequenceId = projectSequenceId;
}
// getters and setters
@Embeddable
public static class ProjectSequenceId implements Serializable {
@Column(name="ID", updatable=false)
private Integer projectId;
@Column(name="REFERENCE", updatable=false)
private String reference;
public ProjectSequenceId() {}
public ProjectSequenceId(Integer projectId, String reference) {
this.projectId = projectId;
this.reference = reference;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ProjectSequenceId))
return false;
final ProjectSequenceId other = (ProjectSequenceId) o;
return new EqualsBuilder().append(getProjectId(), other.getProjectId())
.append(getReference(), other.getReference())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(getProjectId())
.append(getReference())
.hashCode();
}
}
}
这篇关于Hibernate通过在ManyToMany关联上将完全限定的类名添加到属性名而失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!