我使用EclipseLink获得以下异常: 企业实体与客户端实体保持@OneToMany关系。这两个实体都包含在persistance.xml文件中。
我在Enterprise和Client实体中使用内部构建器类,不确定这是否可能是问题。
异常消息
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [geography] failed.
Internal Exception: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: [class za.co.lot24media.ws.entity.Client] uses a non-entity [class za.co.lot24media.ws.entity.Enterprise] as target entity in the relationship attribute [field enterprise].
使用所有选项记录输出
企业
[EL Config]: metadata: 2015-12-24 08:43:26.842--ServerSession(1330106945)--Thread(Thread[main,5,main])--The access type for the persistent class [class za.co.lot24media.ws.entity.Enterprise] is set to [FIELD].
[EL Config]: metadata: 2015-12-24 08:43:27.005--ServerSession(1330106945)--Thread(Thread[main,5,main])--The target entity (reference) class for the many to one mapping element [field enterprise] is being defaulted to: class za.co.lot24media.ws.entity.Enterprise.
[EL Config]: metadata: 2015-12-24 08:43:27.447--ServerSession(1330106945)--Thread(Thread[main,5,main])--The alias name for the entity class [class za.co.lot24media.ws.entity.Enterprise] is being defaulted to: Enterprise.
客户端
[EL Config]: metadata: 2015-12-24 08:43:26.932--ServerSession(1330106945)--Thread(Thread[main,5,main])--The target entity (reference) class for the one to many mapping element [field clients] is being defaulted to: class za.co.lot24media.ws.entity.Client.
[EL Config]: metadata: 2015-12-24 08:43:27.011--ServerSession(1330106945)--Thread(Thread[main,5,main])--The access type for the persistent class [class za.co.lot24media.ws.entity.Client] is set to [FIELD].
[EL Config]: metadata: 2015-12-24 08:43:27.6--ServerSession(1330106945)--Thread(Thread[main,5,main])--The alias name for the entity class [class za.co.lot24media.ws.entity.Client] is being defaulted to: Client.
企业级
package za.co.lot24media.ws.entity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import za.co.lot24media.ws.common.DomainEntity;
/**
*
* @author Hendré Louw <hendre@lot24media.co.za>
*/
@Entity
@Table(name = "enterprise", schema = "enterprise")
public class Enterprise extends DomainEntity<Enterprise> implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "enterprise_id")
private long id;
@OneToOne(optional = false)
@JoinColumn(name = "company_id", nullable = false, unique = true)
private Company company;
@OneToOne(optional = false)
@JoinColumn(name = "configuration_id", nullable = false, unique = true)
private Configuration configuration;
@OneToMany(mappedBy = "enterprise")
private List<Client> clients;
@OneToMany(mappedBy = "enterprise")
private List<Application> applications;
@OneToMany(mappedBy = "enterprise")
private List<Operator> operators;
public Enterprise() {
}
private Enterprise(Builder builder) {
clients = new ArrayList<>();
applications = new ArrayList<>();
operators = new ArrayList<>();
Company c1 = new Company.Builder(this, builder.country, builder.legalPerson, builder.companyName)
.build();
this.company = c1;
this.configuration = builder.configuration;
clients.stream().forEach((c) -> {
c.setEnterprise(this);
});
this.clients.addAll(clients);
applications.stream().forEach((a) -> {
a.setEnterprise(this);
});
this.applications.addAll(applications);
operators.stream().forEach((o) -> {
o.setEnterprise(this);
});
this.operators.addAll(operators);
}
public static class Builder {
private final String companyName;
private final Country country;
private final LegalPerson legalPerson;
private Configuration configuration;
private final List<Client> clients;
private final List<Application> applications;
private final List<Operator> operators;
public Builder(Country country, LegalPerson legalPerson, String companyName) {
assert companyName != null;
assert country != null;
this.country = country;
this.companyName = companyName;
this.legalPerson = legalPerson;
clients = new ArrayList<>();
applications = new ArrayList<>();
operators = new ArrayList<>();
configuration = new Configuration();
}
public Builder withClient(Client client) {
assert client != null;
clients.add(client);
return this;
}
public Builder withApplication(Application application) {
assert application != null;
applications.add(application);
return this;
}
public Builder withOperator(Operator operator) {
assert operator != null;
operators.add(operator);
return this;
}
public Builder withConfiguration(Configuration configuration) {
assert configuration != null;
this.configuration = configuration;
return this;
}
public Enterprise build() {
return new Enterprise(this);
}
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public Configuration getConfiguration() {
return configuration;
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}
public List<Client> getClients() {
return clients;
}
public void setClients(List<Client> clients) {
this.clients = clients;
}
public List<Application> getApplications() {
return applications;
}
public void setApplications(List<Application> applications) {
this.applications = applications;
}
public List<Operator> getOperators() {
return operators;
}
public void setOperators(List<Operator> operators) {
this.operators = operators;
}
}
客户等级
@Entity
@Table(name = "client", schema = "enterprise")
public class Client extends DomainEntity<Client> implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "client_id")
private long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "enterprise_id", nullable = false)
private Enterprise enterprise;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "company_id")
private Company company;
public Client() {
}
客户端静态构建器类
public static class Builder {
private final Enterprise enterprise;
private final Company company;
public Builder(Enterprise enterprise, Company company) {
assert enterprise != null;
assert company != null;
this.enterprise = enterprise;
this.company = company;
}
public Builder(Enterprise enterprise, Country country, LegalPerson legalPerson, String companyName) {
assert enterprise != null;
assert country != null;
assert legalPerson != null;
assert companyName != null;
this.enterprise = enterprise;
this.company = new Company.Builder(enterprise, country, legalPerson, companyName)
.build();
}
public Client build() {
Client c = new Client(this);
// Link enterprise
c.getEnterprise().getClients().add(c);
return c;
}
}