Hi,
i'm using hibernate 3.3.1. and got strange problem:
2008-11-10 16:04:04.828 [ERROR] org.springframework.web.context.ContextLoader (ContextLoader.java:215): Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Duplicate property mapping of _walletsBackref found in entity.Wallet
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1337)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:423)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:830)
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:719)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:490)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.hibernate.MappingException: Duplicate property mapping of _walletsBackref found in entity.Wallet
at org.hibernate.mapping.PersistentClass.checkPropertyDuplication(PersistentClass.java:477)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:467)
at org.hibernate.mapping.RootClass.validate(RootClass.java:215)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:814)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:732)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1368)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1334)
... 39 more
here code of my classes:
Code:
@Entity @Table(name = "Clients")
@SequenceGenerator(name = "ClientIdSeq", sequenceName = "CLIENT_ID_SEQ", allocationSize = 1)
public class Client {
@OneToMany(fetch = FetchType.LAZY) // Seldom used
@Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
@JoinColumn(name="clientId", nullable=false)
protected Set<Account> accounts = new HashSet<Account>();
@OneToMany(fetch = FetchType.LAZY) // Always in payments and info
@Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
@JoinColumn(name="clientId", nullable=false)
protected Set<Wallet> wallets = new HashSet<Wallet>();
}
Code:
@Entity @Table(name = "Accounts", uniqueConstraints = { @UniqueConstraint(
columnNames={"name", "clientid"} ) })
@SequenceGenerator(name = "AccountIdSeq", sequenceName = "ACCOUNT_ID_SEQ", allocationSize = 1)
public class Account {
@ManyToOne(fetch = FetchType.LAZY) // Client is not seldom used
@ForeignKey(name="FK_ACCOUNT_CL")
@JoinColumn(name="clientId", insertable=false, updatable=false, nullable=false)
protected Client client;
@OneToMany(fetch = FetchType.LAZY) //Account always got the wallet
@Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
@JoinColumn(name="accountId", nullable=false)
protected Set<Wallet> wallets = new HashSet<Wallet>();
}
Code:
@Entity @Table(name = "Wallets")
@SequenceGenerator(name = "WalletIdSeq", sequenceName = "WALLET_ID_SEQ", allocationSize = 1)
public class Wallet {
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name="FK_WALLET_CL")
@JoinColumn(name="clientId", insertable=false, updatable=false, nullable=false)
//found bug with hibernate, can't set nallable to false...
protected Client client;
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name="FK_WALLET_AC")
@JoinColumn(name="accountId", insertable=false, updatable=false, nullable=false)
protected Account account;
}
I made hibernate work, but I lost important constraints.
If I change nullability of
Code:
@JoinColumn(name="clientId", nullable=false)
protected Set<Wallet> wallets = new HashSet<Wallet>();
to
true the scheme will be created, but on client save there'll be an error.
Caused by: java.sql.BatchUpdateException: ORA-01400: нево.мо.но встав.т. NULL в ("LGN"."WALLETS"."CLIENTID")
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:770)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:14420)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:588)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
oracle was not able to insert NULL in not null field, cause:
select
CLIENT_ID_SEQ.nextval
from
dual
2008-11-10 16:15:18.703 [DEBUG] org.hibernate.SQL (SQLStatementLogger.java:111):
select
ACCOUNT_ID_SEQ.nextval
from
dual
2008-11-10 16:15:18.703 [DEBUG] org.hibernate.SQL (SQLStatementLogger.java:111):
select
WALLET_ID_SEQ.nextval
from
dual
2008-11-10 16:15:18.703 [DEBUG] org.hibernate.SQL (SQLStatementLogger.java:111):
select
hibernate_sequence.nextval
from
dual
2008-11-10 16:15:18.718 [DEBUG] org.hibernate.SQL (SQLStatementLogger.java:111):
insert
into
Clients
(email, expDate, fullName, grp, openDate, pswd, phoneNumber, status, id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?)
(SQLStatementLogger.java:111):
insert
into
Accounts
(availableBalance, currency, name, openDate, pin, status, type, clientId, id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?)
(SQLStatementLogger.java:111):
insert
into
Wallets
(openDate, spentFunds, status, accountId, id)
values
(?, ?, ?, ?, ?)
he ignored the reference... and finally, if I change the nullability
Code:
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name="FK_WALLET_CL")
@JoinColumn(name="clientId", insertable=false, updatable=false, nullable=true)
//found bug with hibernate, can't set nallable to false...
protected Client client;
than all is correct, but i lost 2 not null constraints. what's wrong in hibernate, why this example caused the duplication?..