2012-10-26 33 views
1

在我的java spring webapp中我有关系:一个帐户可以有多个组,一个组只能有一个帐户。jpa初始化时出现一对多的sql错误

集团法人:

@Entity 
@Table(name = "group") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class Group { 

@Id 
@GeneratedValue(generator = "group_id", strategy = GenerationType.SEQUENCE) 
@SequenceGenerator(name = "group_id", sequenceName = "group_group_id_seq", allocationSize = 1) 
@Column(name = "group_id") 
private Long id; 

@Basic 
@NotBlank 
@Column(name = "name") 
private String name; 

@ManyToOne(targetEntity = Account.class, fetch = FetchType.LAZY) 
@JoinColumn(name = "account_id") 
private Account account; 

@Basic 
@NotBlank 
@Column(name = "all") 
private boolean all; 

@ManyToMany(targetEntity = Word.class, fetch = FetchType.LAZY) 
@JoinTable(name = "group_word", joinColumns = {@JoinColumn(name="group_id")}, inverseJoinColumns = {@JoinColumn(name="word_id")}) 
private List<Word> words; 

getters/setters... 

帐户实体:

@Entity 
@JsonIgnoreProperties(ignoreUnknown = true) 
@Table(name = "account") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class Account extends User implements UserDetails { 

@Id 
@GeneratedValue(generator = "account_id", strategy = GenerationType.SEQUENCE) 
@SequenceGenerator(name = "account_id", sequenceName = "account_account_id_seq", allocationSize = 1) 
@Column(name = "account_id") 
private Long accountId; 

@Column(name = "username") 
private String username; 

@Column(name = "password") 
private String password; 

@Transient 
private String repeatedPassword; 

@DateTimeFormat(iso = ISO.DATE_TIME) 
@Column(name = "registration_date") 
Date registrationDate = Calendar.getInstance().getTime(); 

@Column(name = "email") 
private String email; 

@ManyToMany(targetEntity = Role.class, fetch = FetchType.LAZY) 
@JoinTable(name = "account_role", joinColumns = {@JoinColumn(name="account_id")}, inverseJoinColumns = {@JoinColumn(name="role_id")}) 
private List<Role> roles; 

public List<Role> getRoles() { 
    return roles; 
} 

public void setRoles(List<Role> roles) { 
    this.roles = roles; 
} 

@OneToMany(mappedBy="account", fetch = FetchType.LAZY) 
private List<Group> groups; 

public List<Group> getGroups() { 
    return groups; 
} 

public void setGroups(List<Group> groups) { 
    this.groups = groups; 

getters/setters... 

当我调用此服务方法:

public List<Group> listUserGroups(String username) { 
    try { 
     Account foundAccount = accountDao.findUserByUsername(username); 
     List<Group> userGroups = foundAccount.getGroups(); 
     userGroups.size(); 
     return userGroups; 
    } catch (UserNotFoundException unf) { 
     logger.error("User not found: " + username, unf.getMessage()); 
     return Collections.emptyList(); 
    } 
} 

我有线上的错误:

userGroups.size(); 

错误:

00:27:27,528 DEBUG [org.hibernate.engine.StatefulPersistenceContext] - initializing non-lazy collections 
00:27:27,528 DEBUG [org.hibernate.loader.Loader] - loading collection: [pl.net.grodek.snd.model.Account.groups#116] 
00:27:27,528 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0) 
00:27:27,528 DEBUG [org.hibernate.SQL] - select groups0_.account_account_id as account4_20_1_, groups0_.group_id as group1_1_, groups0_.group_id as group1_19_0_, groups0_.account_account_id as account4_19_0_, groups0_.all as all19_0_, groups0_.name as name19_0_ from group groups0_ where groups0_.account_account_id=? 
00:27:27,544 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1) 
00:27:27,544 DEBUG [org.hibernate.util.JDBCExceptionReporter] - could not initialize a collection: [pl.net.grodek.snd.model.Account.groups#116] [select groups0_.account_account_id as account4_20_1_, groups0_.group_id as group1_1_, groups0_.group_id as group1_19_0_, groups0_.account_account_id as account4_19_0_, groups0_.all as all19_0_, groups0_.name as name19_0_ from group groups0_ where groups0_.account_account_id=?] 
org.postgresql.util.PSQLException: ERROR: syntax error near "group" 
Position: 227 
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103) 
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836) 
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388) 
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273) 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) 
at org.hibernate.loader.Loader.getResultSet(Loader.java:1953) 
at org.hibernate.loader.Loader.doQuery(Loader.java:802) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) 
at org.hibernate.loader.Loader.loadCollection(Loader.java:2166) 
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62) 
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:627) 
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83) 
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1863) 
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:369) 
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111) 
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:134) 
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248) 
at pl.net.grodek.snd.service.GroupServiceImpl.listUserGroups(GroupServiceImpl.java:47) 
at pl.net.grodek.snd.service.GroupServiceImpl.listUserGroups(GroupServiceImpl.java:1) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at 

我认为问题是由JPA生成的查询:

select groups0_.account_account_id as account4_20_1_, groups0_.group_id as group1_1_, groups0_.group_id as group1_19_0_, groups0_.account_account_id as account4_19_0_, groups0_.all as all19_0_, groups0_.name as name19_0_ from group groups0_ where groups0_.account_account_id=? 

那里加倍ACCOUNT_ID和GROUP_ID。但我的问题是为什么发生这种情况。请澄清对于我这个问题,因为我跑出去的想法:(

编辑:

哦,我忘了数据库表:

CREATE TABLE "group" 
(
    group_id bigserial NOT NULL, 
    name character varying(150)[] NOT NULL, 
    "all" boolean NOT NULL DEFAULT false, 
    account_id bigint NOT NULL, 
    CONSTRAINT group_id_pk PRIMARY KEY (group_id), 
    CONSTRAINT account_id_fk FOREIGN KEY (account_id) 
    REFERENCES account (account_id) MATCH SIMPLE 
    ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

CREATE TABLE account 
(
    account_id bigserial NOT NULL, 
    username character varying(32), 
    password character varying(64), 
    email character varying(100), 
    registration_date timestamp with time zone NOT NULL, 
    word_for_today bigint, 
    groups_on_page integer NOT NULL, 
    CONSTRAINT account_pk PRIMARY KEY (account_id), 
    CONSTRAINT word_fk FOREIGN KEY (word_for_today) 
    REFERENCES word (word_id) MATCH SIMPLE 
    ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT unique_mail UNIQUE (email), 
    CONSTRAINT unique_username UNIQUE (username) 
) 
+0

的关系是多对一的组以反映我的映射工作。你不需要连接表。您似乎没有连接表,但您正在使用'@ JoinTable'。 –

+1

我不知道是不是因为“group”实际上是SQL中的一个关键字。如果你改用其他东西,它会起作用吗?你觉得呢 –

+0

?正如你可以在我自己的答案中看到的,我将它改为了组,它的工作原理可能如此,但我不确定为什么这会起作用。 –

回答

0

我将组表名改为组,它起作用。但请任何人都可以告诉我为什么。与早期的关系,我没有这样的神秘问题。我失去了理智。 :(

也许有人在我的代码中看到问题?我的帐户 - >群组关系是否设置良好?

编辑:由于@AdrianShum所述基团是一个SQL关键字,这样,当我换到另一个名称

0

在我的经验,问题与的范围有关持久性上下文 您正在使用DAO来检索实体,因此您可能假装访问某个已去除实体的属性。
说话的光线,也许在accountDao.findUserByUsername()函数的范围内,您会初始化/实例化持久性上下文当你检索一个实体时通过实体管理器,但在对象返回后,此函数的作用域结束以及持久化上下文(entityManager)的实例。换句话说,在Java SE应用程序环境中,您并未以静态方式引用entityManager,以便在所有应用程序运行范围内保持活动状态。

除此之外,Hibernate使用代理。这意味着,按照您的示例,您将检索具有加载的所有基本属性的对象帐户,但相反地,懒惰关系(组,角色等)。 当调用getGroups()不强制代理查询组列表时,但调用大小时,代理必须查询它们。 向这更好undestanding和Hibernate的一般行为,我建议你这本书休眠在行动第13章理解代理 - Java持久性与Hibernate(ISBN 1-932394-88-5)

问候

+0

我认为这不是原因,因为我有其他使用这个道的关系,并没有这样的问题。 –

相关问题