jpa 的映射不能一个两个属性同时对应一个字段吗?

qingzhe2008 2010-05-06 11:52:48
用JPA,不能实体类的两只属性同时映射表的同一字段吗?

我把实体的两个属性映射到同一字段后,一直抱错:

java.lang.ArrayIndexOutOfBoundsException: 38
org.apache.openjpa.meta.ClassMetaData.getExtraFieldDataIndex(ClassMetaData.java:859)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:358)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:774)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:982)
org.apache.openjpa.jdbc.sql.AbstractResult.load(AbstractResult.java:278)
org.apache.openjpa.jdbc.sql.SelectImpl$SelectResult.load(SelectImpl.java:2400)
org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.loadEagerJoin(RelationFieldStrategy.java:541)
org.apache.openjpa.jdbc.meta.FieldMapping.loadEagerJoin(FieldMapping.java:807)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:1048)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.load(JDBCStoreManager.java:1008)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:378)
org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
...


从这个错推测是在把查询结果集封装成实体类时产生的

是我配置错了能,还是根本就不能这样。
...全文
569 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xuhesheng 的回复:]

我觉得不能
比如说
你在程序中向数据库中写入的话
按照映射规则可以将不同的属性写入同一个字段?

或者从数据库写入到java类中
他怎么知道要按照哪一个去映射

当然你是知道的
可是计算机
不会按照你的方式去执行的
因为程序有两个出口。。。。

[/Quote]

有道理。

起始我这么做是原因是:
1、有一个用户类User,一个订单类Orders
User类有一个orders的集合
订单会有很多未付款的订单,少量的付款了的订单

我想要实现的是把orders集合分成两个:nopayOrders 和 paiedOrders 订单有已支付和为支付的标志字段。
而且这两个集合里的对象都只是需要查看,不需要修改的。

所有就做了上面那那种尝试,结果发现不行。

谁还有其他可行的方法吗?

xuhesheng 2010-05-06
  • 打赏
  • 举报
回复
我觉得不能
比如说
你在程序中向数据库中写入的话
按照映射规则可以将不同的属性写入同一个字段?

或者从数据库写入到java类中
他怎么知道要按照哪一个去映射

当然你是知道的
可是计算机
不会按照你的方式去执行的
因为程序有两个出口。。。。

再说了两个属性为什么要映射同一个字段呢
既然是同样的
何必要多余一个。。。
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 zhangjihao 的回复:]

引用 15 楼 qingzhe2008 的回复:
因为unpayOrders和paiedOrders使用的比较平凡
所以,我希望通过映射的配置,在查询的时候就直接把这两个集合初始化了,避免去对较大的结果集进行遍历分类

能实现吗
貌似iBatis框架可以实现,但它似乎没有完全兼容JPA规范。建议在逻辑层实现吧。
[/Quote]

恩,谢谢了,我自己在研究下吧。有结果了,就来告诉大家
howsun_zh 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 qingzhe2008 的回复:]
因为unpayOrders和paiedOrders使用的比较平凡
所以,我希望通过映射的配置,在查询的时候就直接把这两个集合初始化了,避免去对较大的结果集进行遍历分类

能实现吗[/Quote]
貌似iBatis框架可以实现,但它似乎没有完全兼容JPA规范。建议在逻辑层实现吧。
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 minhw 的回复:]

不过还是觉得同一个表中两个相同字段,字段里存不相同的值。。 听起来怎么那么别扭呢,为什么非要自己给自己找难题呢
[/Quote]

???
表中哪有重复字段?

是实体类里有两个类型一样的属性,这两个属性的值将来自于同一张表,只是两个集合中的数据是通过一个标识位来区分开!!!
minhw 2010-05-06
  • 打赏
  • 举报
回复
不过还是觉得同一个表中两个相同字段,字段里存不相同的值。。 听起来怎么那么别扭呢,为什么非要自己给自己找难题呢
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zhangjihao 的回复:]

引用 8 楼 qingzhe2008 的回复:
Java code

User.java
public class User{
...
private Set unpayOrders = new HashSet<Orders>();
private Set paiedOrders = new HashSet<Orders>();
...
}

Orders.java
pu……
[/Quote]

unpayOrders和paiedOrders,这两个字段是没持久化到数据库。

两个表中的关系只是:t_orders中有个user_id的字段。

因为unpayOrders和paiedOrders使用的比较平凡
所以,我希望通过映射的配置,在查询的时候就直接把这两个集合初始化了,避免去对较大的结果集进行遍历分类

能实现吗
minhw 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhangjihao 的回复:]
引用 7 楼 minhw 的回复:
楼上的例子 我认为不恰当。

@ManyToOne 如果使用上 @JoinColumn的话,在数据库中映射成的是三个表。其中中间表中的字段分别以

两张表的名字+"_"+"ID"命名。JoinColumn修改的只是中间表中的一个字段,并不是原来的表。

这就是两张表中有同名字段了。

不知道我说清楚了吗。

呵呵,这位同学不对,@JoinT……
[/Quote]

对我弄错了 是@JoinTable 一对多默认是影射成三个表,如果使用@JoinColumn的话,就成了使用外健了。多谢。

howsun_zh 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qingzhe2008 的回复:]
Java code

User.java
public class User{
...
private Set unpayOrders = new HashSet<Orders>();
private Set paiedOrders = new HashSet<Orders>();
...
}

Orders.java
public class Ord……
[/Quote]
unpayOrders和paiedOrders两个属性是不可映射到表中的,只能与User表生成关系。但这种关系却是重复的,因此没有意义。我建议将此两个属性设为非持久的,再在逻辑层通过条件查询为此两个属性赋值。示例如下:

User.java

@Entity
public class User{
...
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="user")
private Set<Orders> orders = new HashSet<Orders>();

@Transient
private Set unpayOrders = new HashSet<Orders>();
@Transient
private Set paiedOrders = new HashSet<Orders>();
...
}

Orders.java

@Entity
public class Orders{
private Boolean hasPaied;// 0:已支付 1:未支付

@ManyToOne(cascade=CascadeType.REFRESH,optional=false,fetch=FetchType.LAZY)
@JoinColumn(name="user")
private User user;
}

//逻辑层:
User user = orm.getUser(xxx);
user.setUnpayOrders(orm.getOrders(user,1 or true));
user.setPaiedOrders(orm.getOrders(user,0 or false));


但实际项目中,觉得没必要这么做,直接为orders属性赋值,而支付状态的区别,在展现层就可以解决。
auklli 2010-05-06
  • 打赏
  • 举报
回复
一个字段映射两个属性应该不行
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
知道,怎么能实现我上面那个需求吗?
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhangjihao 的回复:]

呵呵,这位同学不对,@JoinTable才会映射成三个表(中间表),@JoinColumn不可能的
[/Quote]

没错
howsun_zh 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 minhw 的回复:]
楼上的例子 我认为不恰当。

@ManyToOne 如果使用上 @JoinColumn的话,在数据库中映射成的是三个表。其中中间表中的字段分别以

两张表的名字+"_"+"ID"命名。JoinColumn修改的只是中间表中的一个字段,并不是原来的表。

这就是两张表中有同名字段了。

不知道我说清楚了吗。
[/Quote]
呵呵,这位同学不对,@JoinTable才会映射成三个表(中间表),@JoinColumn不可能的
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复

User.java
public class User{
...
private Set unpayOrders = new HashSet<Orders>();
private Set paiedOrders = new HashSet<Orders>();
...
}

Orders.java
public class Orders{
private String hasPaied;// 0:已支付 1:未支付
private User user;
}



要实现这个映射,怎么进行配置呢???
minhw 2010-05-06
  • 打赏
  • 举报
回复
楼上的例子 我认为不恰当。

@ManyToOne 如果使用上 @JoinColumn的话,在数据库中映射成的是三个表。其中中间表中的字段分别以

两张表的名字+"_"+"ID"命名。JoinColumn修改的只是中间表中的一个字段,并不是原来的表。

这就是两张表中有同名字段了。

不知道我说清楚了吗。
howsun_zh 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qingzhe2008 的回复:]
引用 3 楼 zhangjihao 的回复:

可以,在一对一关联时会用到。楼主贴出代码方可诊断


一对多可以吗?

能给个例子吗?
[/Quote]
例如:
一个账户表对应一个用户基本信息表
Account.class
BaseInfo.class

public class BaseInfo implements Serializable{
@Id
@Column(name="id",length=36)
private String username;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
private Account account;
}


可见username和account两个属性对应同一个名为id的字段
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhangjihao 的回复:]

可以,在一对一关联时会用到。楼主贴出代码方可诊断
[/Quote]

一对多可以吗?

能给个例子吗?
qingzhe2008 2010-05-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhangjihao 的回复:]

可以,在一对一关联时会用到。楼主贴出代码方可诊断
[/Quote]

多对一可以吗???
howsun_zh 2010-05-06
  • 打赏
  • 举报
回复
可以,在一对一关联时会用到。楼主贴出代码方可诊断

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧