获取@OneToMany关联中的列表?

时间:2013-04-14 20:56:24

标签: database jpa relational-database jpa-2.0 eclipselink

问题是,user有一个或多个properties,这就是为什么这就是我的实体类user

@Entity
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

        // others attributes  

    //bi-directional many-to-one association to Property
    @OneToMany(mappedBy="user", fetch=FetchType.EAGER)
    private List<Property> properties;
    ..
}

我的实体property

@Entity
public class Property implements Serializable {
  private static final long serialVersionUID = 1L;
  ..
  //bi-directional many-to-one association to User
  @ManyToOne
  @JoinColumn(name="id_user")
  private User user;
  ..
}

这些实体由EclipseLink生成。

这是我的桌子,我认为这对我想要的东西都可以。

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
   ..
   PRIMARY KEY (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`),
  KEY `u_id_city_to_ac_id_idx` (`id_city`),
  KEY `u_id_state_to_as_id_idx` (`id_state`),
  KEY `u_id_country_to_acy_id_idx` (`id_country`),
  CONSTRAINT `u_id_city_to_ac_id` FOREIGN KEY (`id_city`) REFERENCES `address_city` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `u_id_country_to_acy_id` FOREIGN KEY (`id_country`) REFERENCES `address_country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `u_id_state_to_as_id` FOREIGN KEY (`id_state`) REFERENCES `address_state` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8 COMMENT='an user can be a tenant and a landlord also';

我的property表:

CREATE TABLE `property` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_user` int(11) unsigned NOT NULL,
   ..
    PRIMARY KEY (`id`),
  KEY `p_id_accomodation_to_pac_id_idx` (`id_accomodation`),
  KEY `p_id_room_type_to_prt_id_idx` (`id_room_type`),
  KEY `p_id_bed_type_to_pbt_id_idx` (`id_bed_type`),
  KEY `p_id_policty_cancelation_to_pc_id_idx` (`id_policy_cancelation`),
  KEY `p_id_user_to_u_id_idx` (`id_user`),
  KEY `p_id_city_to_ac_id_idx` (`id_city`),
  KEY `p_id_state_to_as_id_idx` (`id_state`),
  KEY `p_id_country_to_acy_id_idx` (`id_country`),
  CONSTRAINT `p_id_accomodation_to_pac_id` FOREIGN KEY (`id_accomodation`) REFERENCES `property_accomodation` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `p_id_bed_type_to_pbt_id` FOREIGN KEY (`id_bed_type`) REFERENCES `property_bed_type` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `p_id_city_to_ac_id` FOREIGN KEY (`id_city`) REFERENCES `address_city` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `p_id_country_to_acy_id` FOREIGN KEY (`id_country`) REFERENCES `address_country` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `p_id_policty_cancelation_to_pc_id` FOREIGN KEY (`id_policy_cancelation`) REFERENCES `policy_cancellation` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `p_id_room_type_to_prt_id` FOREIGN KEY (`id_room_type`) REFERENCES `property_room_type` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `p_id_state_to_as_id` FOREIGN KEY (`id_state`) REFERENCES `address_state` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `p_id_user_to_u_id` FOREIGN KEY (`id_user`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

我想在登录操作中获取properties的所有user,例如:

user = userEAO.find(user.getEmail());
user.getProperties(); //always empty

我该怎么做?我认为提出哪种类型fetching,但似乎不是。

更新 我改为LAZY我的FetchType,现在看:

//与Property的双向多对一关联 @OneToMany(mappedBy =“user”,fetch = FetchType.LAZY) 私人列表属性;

user登录系统时:

User u = userEAO.findByEmail(profile.getEmail());
if (u != null){
  if (u.getProperties() != null){
    u.getProperties().size();
    System.out.println(u.getProperties().size()); // now prints 1
}

詹姆斯,在为property创建新的user时,这就是您的意思,refreshing对象property,对吗?是的,在创建此property之后,我将其添加到user列表properties =]

public Message create(Property property) {
        try{
            em.persist(property);
            em.flush();
            em.refresh(property);
        }catch(ConstraintViolationException cve){
            cve.printStackTrace();

        }catch (Exception e) {
            e.printStackTrace();
            // 1062 : duplicate entry
            if (e.getMessage().contains("Duplicate"))
                return new Message(-1000);
            else{
                e.printStackTrace();
                return new Message(-1);
            }
        }
        return new Message(0);
    }

2 个答案:

答案 0 :(得分:2)

FetchType.EAGER表示将在同一时间检索您的Property列表。 LAZY表示只要您致电getProperties().anyMethod(),我们就会检索您的列表。但是,条件是您的User对象由JPA管理(意味着它当前存在管理您的实体实例的EntityManager实例)。

渴望的兴趣是,即使EntityManager已经关闭(例如,您的基础交易已经关闭),您也可以访问您的列表。懒惰的一个是你没有执行查询并在内存中映射对象直到它们被有效使用

因此,在您的情况下,如果列表为空,则与获取模式无关(您在检索用户后立即显式调用getProperties()),但这是因为您在数据库中没有数据或者映射。

答案 1 :(得分:1)

确保在保留用户对象时设置属性。当您持久保存新属性时,请确保设置其用户并将该属性添加到用户的属性中。你需要保持双向关系的双方。

您也可以尝试执行refresh()。