2012-04-06 43 views
1

我有角色实体,它与Page,ProfileSection和PageComponents有三个多对多的映射。当我加载角色页面正确加载,但profileSection和PageComponents只加载一个记录。休眠多对多的结果并不如预期 - 只有最后一条记录被提取

下面是我的模型。

@Entity 
@Table(name = "role", uniqueConstraints = {@UniqueConstraint(columnNames={"authority"})}) 
public class Role extends AbstractBaseModel implements GrantedAuthority { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @BusinessKey(include = MethodType.TO_STRING) 
    private int id; 

    @BusinessKey 
    private String authority; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    //@Fetch(value = FetchMode.SUBSELECT) 
    private Set<Page> pages; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    //@Fetch(value = FetchMode.SUBSELECT) 
    private Set<PageComponent> pageComponents; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    @Fetch(value = FetchMode.SELECT) 
    private Set<ProfileSection> profileSections; 
} 

Page.java

@XmlRootElement(name="page") 
@Entity 
@Table(name = "page", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = {"page_id", "page_title"})}) 
public class Page extends OrderedModel { 
    private static final long serialVersionUID = 1L; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "page_id") 
    private String pageId; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "page_title") 
    private String pageTitle; 

    @BusinessKey 
    @OneToMany(mappedBy="page", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private List<PageComponent> pageComponents; 
} 

ProfileSection.java

@Entity 
@Table(name = "profile_section", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = "section_id")}) 
public class ProfileSection extends OrderedModel { 
    private static final long serialVersionUID = 1L; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "section_id") 
    private String sectionId; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "section_title") 
    private String sectionTitle; 
} 

PageComponent.java

@Entity 
@Table(name = "page_component", catalog = "public", uniqueConstraints = {@UniqueConstraint(columnNames = "component_id")}) 
public class PageComponent extends BaseModel { 
    private static final long serialVersionUID = 1L; 

    @BusinessKey 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="page_id") 
    private Page page; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "component_id") 
    private String componentId; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "component_title") 
    private String componentTitle; 

    @BusinessKey(include = MethodType.TO_STRING) 
    @Column(name = "component_type") 
    private String componentType; 
} 

而在我的DAO代码如下

List<Person> list = c.list(); 
for(Person p: list){ 
    System.out.println("Roles size is:: "+p.getRoles().size()); 
    Role r = p.getRoles().iterator().next(); 
    System.out.println("Page Size is: "+r.getPages().size()); 
    System.out.println("ProfileSection Size is: "+r.getProfileSections().size()); 
    System.out.println("Page Components Size is: "+r.getPageComponents().size()); 
    for(ProfileSection s : r.getProfileSections()) { 
     System.out.println(s.getSectionId()); 
    } 
} 

结果是:

Roles size is:: 1 - Expected 1 

Page Size is: 6 - Expected 6 

ProfileSection Size is: 1 - Expected 3 

Page Components Size is: 1 - Expected 4 

我根据你提供的链接修改了Role.java。下面是修改后的实体

@Entity 
@Table(name = "role", uniqueConstraints = {@UniqueConstraint(columnNames={"authority"})}) 
public class Role extends AbstractBaseModel implements GrantedAuthority{ 


    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @BusinessKey(include = MethodType.TO_STRING) 
    private int id; 

    @BusinessKey 
    private String authority; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinTable(name="role_page", 
     joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")}, 
     inverseJoinColumns={@JoinColumn(name="pages_id", referencedColumnName="id")}) 
    private Set<Page> pages; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinTable(name="role_page_component", 
     joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")}, 
     inverseJoinColumns={@JoinColumn(name="pagecomponents_id", referencedColumnName="id")}) 
    private Set<PageComponent> pageComponents; 

    @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinTable(name="role_profile_section", 
     joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")}, 
     inverseJoinColumns={@JoinColumn(name="profilesections_id", referencedColumnName="id")}) 
    private Set<ProfileSection> profileSections; 

} 

及以下的DAO代码:

/** 
    * For Depth > 1, better use this method method. 
    * Example: Person person = personDAO.findByProperty("email", email, lazyOptions, true); 
    */ 
    @SuppressWarnings("unchecked") 
    public T findByProperty(String propertyName, Object value, HibernateCriteriaLazyOptions lazyOptions, boolean uniqueResult) { 
     JoinCriteriaHelper joiner = JoinCriteriaHelper.forClass(getGenericClass(), lazyOptions.getPaths()); 
     Criteria c; 
     if(lazyOptions.getDepth() != null){ 
      // this would only fetch properties a, b and e 
      c = joiner.getExecutableCriteria(getSession(), lazyOptions.getDepth()); 
      //DetachedCriteria dc = joiner.getDetachedCriteria(Preload.DEPTH_2); 
     }else{ 
      // this would fetch all properties a, b, c, d and e 
      c = joiner.getExecutableCriteria(getSession()); 
     } 
     c.add(Restrictions.eq(propertyName, value)); 

     if(getGenericClass().equals(Person.class)){ 
      List<Person> list = c.list(); 
      for(Person p: list){ 
       System.out.println("Roles size is:: "+p.getRoles().size()); 
       Role r = p.getRoles().iterator().next(); 
       System.out.println("Page Size is: "+r.getPages().size()); 
       System.out.println("ProfileSection Size is: "+r.getProfileSections().size()); 
       System.out.println("Page Components Size is: "+r.getPageComponents().size()); 
       for(ProfileSection s : r.getProfileSections()){ 
        System.out.println(s.getSectionId()); 
       } 
      } 
     } 
     return (T)UnproxyUtility.unproxy((T)c.uniqueResult()); 
    } 

下面是我的表:

CREATE TABLE "role" 
(
    id integer NOT NULL, 
    authority character varying(255), 
    CONSTRAINT role_pkey PRIMARY KEY (id), 
    CONSTRAINT role_authority_key UNIQUE (authority) 
) 

CREATE TABLE page 
(
    id bigserial NOT NULL, 
    created_date timestamp without time zone, 
    last_updated timestamp without time zone, 
    page_id character varying(255), 
    page_title character varying(255), 
    order_number bigint, 
    CONSTRAINT page_pkey PRIMARY KEY (id), 
    CONSTRAINT page_page_id_key UNIQUE (page_id), 
    CONSTRAINT page_page_id_key1 UNIQUE (page_id), 
    CONSTRAINT page_page_title_key UNIQUE (page_title) 
) 

CREATE TABLE role_page 
(
    role_id integer NOT NULL, 
    pages_id bigint NOT NULL, 
    CONSTRAINT role_page_pkey PRIMARY KEY (role_id, pages_id), 
    CONSTRAINT fk140574b8dc0483c9 FOREIGN KEY (pages_id) 
     REFERENCES page (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT fk140574b8facefbbe FOREIGN KEY (role_id) 
     REFERENCES "role" (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

CREATE TABLE page_component 
(
    id bigserial NOT NULL, 
    created_date timestamp without time zone, 
    last_updated timestamp without time zone, 
    component_id character varying(255), 
    component_title character varying(255), 
    component_type character varying(255), 
    page_id bigint, 
    CONSTRAINT page_component_pkey PRIMARY KEY (id), 
    CONSTRAINT fk5b31d34d78d7191e FOREIGN KEY (page_id) 
     REFERENCES page (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT page_component_component_id_key UNIQUE (component_id) 
) 

CREATE TABLE role_page_component 
(
    role_id integer NOT NULL, 
    pagecomponents_id bigint NOT NULL, 
    CONSTRAINT role_page_component_pkey PRIMARY KEY (role_id, pagecomponents_id), 
    CONSTRAINT fk8af50636d6882e9f FOREIGN KEY (pagecomponents_id) 
     REFERENCES page_component (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT fk8af50636facefbbe FOREIGN KEY (role_id) 
     REFERENCES "role" (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

CREATE TABLE profile_section 
(
    id bigserial NOT NULL, 
    created_date timestamp without time zone, 
    last_updated timestamp without time zone, 
    order_number bigint, 
    section_id character varying(255), 
    section_title character varying(255), 
    CONSTRAINT profile_section_pkey PRIMARY KEY (id), 
    CONSTRAINT profile_section_section_id_key UNIQUE (section_id), 
    CONSTRAINT profile_section_section_id_key1 UNIQUE (section_id) 
) 

CREATE TABLE role_profile_section 
(
    role_id integer NOT NULL, 
    profilesections_id bigint NOT NULL, 
    CONSTRAINT role_profile_section_pkey PRIMARY KEY (role_id, profilesections_id), 
    CONSTRAINT fkcac52086b893cd43 FOREIGN KEY (profilesections_id) 
     REFERENCES profile_section (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT fkcac52086facefbbe FOREIGN KEY (role_id) 
     REFERENCES "role" (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

下面是Hibernate执行查询:

Hibernate: select pages0_.role_id as role1_22_1_, pages0_.pages_id as pages2_1_, page1_.ID as ID17_0_, page1_.created_date as created2_17_0_, page1_.last_updated as last3_17_0_, page1_.order_number as order4_17_0_, page1_.page_id as page5_17_0_, page1_.page_title as page6_17_0_ from role_page pages0_ inner join public.page page1_ on pages0_.pages_id=page1_.ID where pages0_.role_id=? 

Page Size is: 6 

Hibernate: select profilesec0_.role_id as role1_22_1_, profilesec0_.profilesections_id as profiles2_1_, profilesec1_.ID as ID19_0_, profilesec1_.created_date as created2_19_0_, profilesec1_.last_updated as last3_19_0_, profilesec1_.order_number as order4_19_0_, profilesec1_.section_id as section5_19_0_, profilesec1_.section_title as section6_19_0_ from role_profile_section profilesec0_ inner join public.profile_section profilesec1_ on profilesec0_.profilesections_id=profilesec1_.ID where profilesec0_.role_id=? 

ProfileSection Size is: 1 

Hibernate: select pagecompon0_.role_id as role1_22_1_, pagecompon0_.pagecomponents_id as pagecomp2_1_, pagecompon1_.ID as ID18_0_, pagecompon1_.created_date as created2_18_0_, pagecompon1_.last_updated as last3_18_0_, pagecompon1_.component_id as component4_18_0_, pagecompon1_.component_title as component5_18_0_, pagecompon1_.component_type as component6_18_0_, pagecompon1_.page_id as page7_18_0_ from role_page_component pagecompon0_ inner join public.page_component pagecompon1_ on pagecompon0_.pagecomponents_id=pagecompon1_.ID where pagecompon0_.role_id=? 

Page Components Size is: 1 

如果您观察结果ts:

Pages are getting 6 - This is expected as the rows are 6 for that particular role id 

PageComponents 1 - This is wrong as the rows matching for that role id are 4 

ProfileSections 1 - This is also wrong matching rows are 4. 

我无法理解我错在哪里。我根据这些建议更新了我的实体,但结果仍不如预期。这不是我第一次从事多对多的工作,到目前为止我从来没有遇到过这样的问题。即使我得到了预期的结果,甚至没有在Role.java中映射joinTable。

请让我知道我错了吗?

+0

您可以在填充时显示代码,也可以在连接表中打印出来吗? – barsju 2012-04-06 22:11:19

+0

我发布了我的代码。请看一看。 – SateeshKasaboina 2012-04-08 09:04:00

回答

0

我不完全确定它为什么会根本返回Page,ProfileSectionPageComponent。它看起来并不像你用Manyou to Manys登录@JoinTable@JoinColumn注释。也许你是通过XML来完成的?在这种情况下,你可以发布你的连接定义吗?

请参阅this site了解有关使用注释连接ManyToManys的说明。

+0

我添加了我的评论请看看它。 – SateeshKasaboina 2012-04-07 18:13:07

+0

我不熟悉'JoinCriteriaHelper',但这肯定是你考虑到它部分调整延迟初始化(根据这个源代码)(http://bwinterberg.blogspot。COM/2009/09 /休眠 - 预压pattern.html))。你有没有试过用老式的'@ NamedQuery'来获取默认的Hibernate行为? – 2012-04-08 18:02:09

+0

我将集合映射从Set更改为List。现在我正在获取所有行。为什么当我使用Set进行映射集合时,我只获得最后一行? – SateeshKasaboina 2012-04-09 15:40:23