0

问题是,一个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;

我想获取所有登录操作propertiesuser例如:

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

我怎样才能做到这一点 ?我认为放置哪种类型fetching就足够了,但似乎不是。

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

//与属性的双向多对一关联 @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这就是你的意思,对吧?是的,创建后我将它添加到列表中=]refreshingpropertypropertyuserproperties

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);
    }
4

2 回答 2

2

FetchType.EAGER意味着您的Property列表将与对象同时被检索。LAZY意味着您的列表将在您调用时立即被检索getProperties().anyMethod()。但是,条件是您的User对象仍由 JPA 管理(意味着它当前存在EntityManager管理您的实体实例的实例)。

Eager 的兴趣在于,即使列表EntityManager已关闭(例如,您的基础交易已关闭),您也可以访问您的列表。一种懒惰的做法是,在有效使用对象之前,您不会在内存中执行查询和映射对象

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

于 2013-04-14T21:41:34.247 回答
1

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

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

于 2013-04-15T13:18:29.853 回答