Я сделал тот же сценарий, предложенный вашим вопросом.И, как и ожидалось, я получаю то же исключение.Так же, как дополнительная задача, я выполнил тот же сценарий , но с одним ко многим, многие к одному , используя не первичный ключ в качестве объединенного столбца , например, ссылку.Теперь я получаю
SecondaryTable JoinColumn не может ссылаться на не первичный ключ
Ну, это может быть ошибкой ???Ну, да (и ваш обходной путь отлично работает (+1)).Если вы хотите использовать не первичный ключ в качестве первичного ключа , вы должны убедиться, что он уникален .Возможно, это объясняет, почему Hibernate не позволяет использовать не первичный ключ в качестве первичного ключа (пользователи, не знающие о себе, могут получить непредвиденное поведение).
Если вы хотите использовать одно и то же сопоставление, вы можете разделить ваши отношения @ManyToMany на @ OneToMany-ManyToOne Используя инкапсуляцию , вам не нужно беспокоиться о вашем присоединенном классе
Проект
@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();
}
}
}