使用Eclipselink JPA通过代码(非ID)链接两个对象
我有两张桌子:使用Eclipselink JPA通过代码(非ID)链接两个对象,jpa,eclipselink,Jpa,Eclipselink,我有两张桌子: area ( id int PK autoincrement code varchar ) products ( id int PK autoincrement area_id int ) 对象的定义如下: class Product { ... @JoinColumn(name = "area_id", referencedColumnName = "id") @ManyToOne @Expose private Ar
area (
id int PK autoincrement
code varchar
)
products (
id int PK autoincrement
area_id int
)
对象的定义如下:
class Product {
...
@JoinColumn(name = "area_id", referencedColumnName = "id")
@ManyToOne
@Expose
private Area area;
...
}
@Entity
@SecondaryTable(name="area", pkJoinColumns=@PrimaryKeyJoinColumn(name="id", referencedColumnName="area_id"))
class Product {
...
@Column(name="code", table = "area")
private String code;
...
}
@Transformation(fetch = FetchType.EAGER, optional = false)
@ReadTransformer(transformerClass = AreaAttributeTransformer.class)
@WriteTransformers({
@WriteTransformer(
transformerClass = AreaFieldTransformer.class,
column = @Column(name = "area_id", nullable = false))
})
@Expose
private String area;
这很好,但我希望该区域是一个字符串,包含表area列code中使用的代码
class Product {
...
???
private String area;
...
}
什么样的注释才能使这项工作有效
谢谢 尝试使用和注释的组合。大概是这样的:
class Product {
...
@JoinColumn(name = "area_id", referencedColumnName = "id")
@ManyToOne
@Expose
private Area area;
...
}
@Entity
@SecondaryTable(name="area", pkJoinColumns=@PrimaryKeyJoinColumn(name="id", referencedColumnName="area_id"))
class Product {
...
@Column(name="code", table = "area")
private String code;
...
}
@Transformation(fetch = FetchType.EAGER, optional = false)
@ReadTransformer(transformerClass = AreaAttributeTransformer.class)
@WriteTransformers({
@WriteTransformer(
transformerClass = AreaFieldTransformer.class,
column = @Column(name = "area_id", nullable = false))
})
@Expose
private String area;
如果有一个可怜的灵魂也有同样的问题,我是这样做的: 使用变压器。因此,字段区域的定义如下:
class Product {
...
@JoinColumn(name = "area_id", referencedColumnName = "id")
@ManyToOne
@Expose
private Area area;
...
}
@Entity
@SecondaryTable(name="area", pkJoinColumns=@PrimaryKeyJoinColumn(name="id", referencedColumnName="area_id"))
class Product {
...
@Column(name="code", table = "area")
private String code;
...
}
@Transformation(fetch = FetchType.EAGER, optional = false)
@ReadTransformer(transformerClass = AreaAttributeTransformer.class)
@WriteTransformers({
@WriteTransformer(
transformerClass = AreaFieldTransformer.class,
column = @Column(name = "area_id", nullable = false))
})
@Expose
private String area;
然后这些类别的工作原理如下:
class Product {
...
@JoinColumn(name = "area_id", referencedColumnName = "id")
@ManyToOne
@Expose
private Area area;
...
}
@Entity
@SecondaryTable(name="area", pkJoinColumns=@PrimaryKeyJoinColumn(name="id", referencedColumnName="area_id"))
class Product {
...
@Column(name="code", table = "area")
private String code;
...
}
@Transformation(fetch = FetchType.EAGER, optional = false)
@ReadTransformer(transformerClass = AreaAttributeTransformer.class)
@WriteTransformers({
@WriteTransformer(
transformerClass = AreaFieldTransformer.class,
column = @Column(name = "area_id", nullable = false))
})
@Expose
private String area;
AreaAttributeTransformer
public class AreaAttributeTransformer implements AttributeTransformer {
private AbstractTransformationMapping mapping;
@Override
public void initialize(AbstractTransformationMapping abstractTransformationMapping) {
this.mapping = abstractTransformationMapping;
}
@Override
public Object buildAttributeValue(Record record, Object o, Session session) {
for (DatabaseField field : mapping.getFields()) {
if (field.getName().contains("area_id")) {
EntityManager em = MyEntityManagerFactory.getENTITY_MANAGER_FACTORY().createEntityManager();
List results = em.createNamedQuery("Areas.findById")
.setParameter("id", record.get(field))
.getResultList();
if (results.size() > 0)
return ((Area) results.get(0)).getCode();
}
}
return null;
}
public class AreaFieldTransformer implements FieldTransformer {
private AbstractTransformationMapping mapping;
@Override
public void initialize(AbstractTransformationMapping abstractTransformationMapping) {
this.mapping = abstractTransformationMapping;
}
@Override
public Object buildFieldValue(Object o, String s, Session session) {
if (o instanceof RouSub) {
EntityManager em = MyEntityManagerFactory.getENTITY_MANAGER_FACTORY().createEntityManager();
List results = em.createNamedQuery("Area.findByCode")
.setParameter("area", ((Area) o).getCode())
.getResultList();
if (results.size() > 0)
return ((Area)results.get(0)).getId();
}
return null;
}
}
AreaFieldTransformer
public class AreaAttributeTransformer implements AttributeTransformer {
private AbstractTransformationMapping mapping;
@Override
public void initialize(AbstractTransformationMapping abstractTransformationMapping) {
this.mapping = abstractTransformationMapping;
}
@Override
public Object buildAttributeValue(Record record, Object o, Session session) {
for (DatabaseField field : mapping.getFields()) {
if (field.getName().contains("area_id")) {
EntityManager em = MyEntityManagerFactory.getENTITY_MANAGER_FACTORY().createEntityManager();
List results = em.createNamedQuery("Areas.findById")
.setParameter("id", record.get(field))
.getResultList();
if (results.size() > 0)
return ((Area) results.get(0)).getCode();
}
}
return null;
}
public class AreaFieldTransformer implements FieldTransformer {
private AbstractTransformationMapping mapping;
@Override
public void initialize(AbstractTransformationMapping abstractTransformationMapping) {
this.mapping = abstractTransformationMapping;
}
@Override
public Object buildFieldValue(Object o, String s, Session session) {
if (o instanceof RouSub) {
EntityManager em = MyEntityManagerFactory.getENTITY_MANAGER_FACTORY().createEntityManager();
List results = em.createNamedQuery("Area.findByCode")
.setParameter("area", ((Area) o).getCode())
.getResultList();
if (results.size() > 0)
return ((Area)results.get(0)).getId();
}
return null;
}
}为什么不保留映射并在需要代码时使用area.code呢?我正在实现json rest API,我想让它尽可能简单。我希望用户只发送代码,而不需要知道area.id是什么。不要将实体类和webservices类混合在一起,这样您就不会有这样的问题。您的EJB类应该只对数据库建模,您需要为Web服务创建另一组类,并在它们之间映射数据!谢谢你的回复。这对于GET方法很有效,但是PUT呢?异常说明:缺少字段[area.id]的映射。Descriptor:RelationalDescriptor(xxx.Product-->[DatabaseTable(products),DatabaseTable(area)]@MarianoL您是否尝试使用已存在或不存在的区号保存新产品?另外,请看一下这个问题