This is the current structure of the Informix Database:
Table: msg_body
id (PK)
kanal
sender
...
Table: msg_user
id (PK, FK)
empfaenger (PK)
datum
...
A msg_user has one or more msg_bodies.
msg_body domain class:
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
@Entity
@Table(name="msg_body")
public class MessageBody implements Serializable {
@Id
@Column(name="id")
private int mb_id;
@Column(name="kanal")
private String channel;
@Column(name="gueltig_von")
private Timestamp validFrom;
@Column(name="gueltig_bis")
private Timestamp validTo;
@Column(name="sender")
private String sender;
@Column(name="erstell_datum")
private Timestamp createDate;
@Column(name="prioritaet")
private int priority;
@Column(name="nachricht")
private String message;
@Column(name="info")
private String info;
@Column(name="gueltig")
private char valid;
@ManyToOne
private MessageUser messageUser;
//getter + setter
}
msg_user domain class:
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
@Entity
@Table(name="msg_user")
public class MessageUser implements Serializable {
@EmbeddedId
UserId mu_id;
@MapsId("mb_id")
@JoinColumn(name = "mu_id", referencedColumnName = "id")
@OneToMany
private Set<MessageBody> msg_bodies = new HashSet<>();
@Column(name = "datum")
private Timestamp receiverDate;
@Column(name = "versuch")
private Timestamp tryTime;
@Column(name = "versuch_anzahl")
private int tryAmount;
@Column(name = "status")
private int state;
@Column(name = "ip")
private char ip;
// getter + setter + hashcode + equals
}
Composite Key Class:
import java.io.Serializable;
import javax.persistence.*;
@Embeddable
public class UserId implements Serializable
{
@Column(name="id")
private int mb_id;
@Column(name="empfaenger")
private String receiver;
// getter + setter + hashcode + equals
}
Application class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@ComponentScan("at.company.badge_service")
@EnableAutoConfiguration
@EnableJpaRepositories(basePackages = {"at.company.badge_service.repository"})
public class Application extends SpringBootServletInitializer
{
public static void main (String[] args)
{
SpringApplication.run(Application.class, args);
}
}
The goal is to run this statement:
public interface BARepository extends JpaRepository<MessageBody, Long>
{
@Query( "SELECT COUNT(mu.id) FROM MessageUser mu WHERE mu.receiver = :username")
Long countBA(@Param("username") String username);
}
application.properties file:
spring.main.show-banner=false
security.basic.enabled=false
spring.thymeleaf.cache=false
# JACKSON
spring.jackson.mapper.default-view-inclusion=true
#spring.jackson.deserialization.fail-on-unknown-properties=false
security.user.name: username
security.user.password: password
spring.view.prefix: /WEB-INF/views/
spring.view.suffix: .jsp
# DATABASE
spring.jpa.database: INFORMIX
spring.jpa.hibernate.ddl-auto: validate
spring.jpa.properties.hibernate.default_batch_fetch_size: 100
spring.datasource.jndi-name=jdbc/msgdb
ErrorCode NullpointerException:
2015-04-24 09:30:04,702 [RMI TCP Connection(3)-127.0.0.1] ERROR o.s.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_02]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_02]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_02]
Caused by: java.lang.NullPointerException: null
Apr 24, 2015 9:30:04 AM org.apache.catalina.core.ContainerBase addChildInternal
at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1460) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:864) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
Schwerwiegend: ContainerBase.addChild: start:
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:779) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/badge_service]]
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:728) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426) ~[hibernate-core-4.3.7.Final.jar:4.3.7.Final]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562) ~[spring-beans-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565)
... 58 common frames omitted
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 40 more
Caused by: java.lang.NullPointerException
at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1460)
at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:864)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
... 58 more
Apr 24, 2015 9:30:04 AM org.apache.tomcat.util.modeler.BaseModelMBean invoke
Schwerwiegend: Exception invoking method manageApp
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/badge_service]]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:904)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Apr 24, 2015 9:30:04 AM org.apache.tomcat.util.modeler.BaseModelMBean invoke
Schwerwiegend: Exception invoking method createStandardContext
javax.management.RuntimeOperationsException: Exception invoking method manageApp
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:309)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:791)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/badge_service]]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:904)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
... 31 more
I tried to find a solution on the web, but none of them worked in my case. Especially the foreign key in the composite key seems to be a rare problem. I'm well aware, that it would be much easier to add a surrogate key to the msg_user-table, but I have to solve exactly this problem, so I would be happy if someone could show me how to code the domain classes with the relations in the right way. If you need further information do not hesitate to ask for them! Many thanks in advance!
After a while I found myself a solution:
MessageBody domainclass:
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name="msg_body")
public class MessageBody implements Serializable
{
@Id
@Column(name="id")
private int msgb_id;
@Column(name="kanal", columnDefinition = "char")
private String channel;
@Column(name="gueltig_von")
private Timestamp validFrom;
@Column(name="gueltig_bis")
private Timestamp validTo;
@Column(name="sender")
private String sender;
@Column(name="erstell_datum")
private Timestamp createDate;
@Column(name="prioritaet")
private int priority;
@Column(name="nachricht")
private String message;
@Column(name="info", columnDefinition = "lvarchar")
private String info;
@Column(name="gueltig")
private char valid;
@OneToMany
@JoinColumn(name = "id")
private Set<MessageUser> message_users = new HashSet<>();
// getter + setter
}
CompositeKey domainclass:
import java.io.Serializable;
import javax.persistence.*;
@Embeddable
public class MessageUserPK implements Serializable
{
private int mb_id;
private String receiver;
// getter + setter + hashcode + equals
}
MessageUser domainclass:
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.*;
@Entity
@Table(name="msg_user")
public class MessageUser implements Serializable
{
@EmbeddedId
@AttributeOverrides
({
@AttributeOverride(name = "mb_id", column = @Column(name = "id")),
@AttributeOverride(name = "receiver", column = @Column(name = "empfaenger"))
})
MessageUserPK mu_id;
@Column(name = "datum")
private Timestamp receiverDate;
@Column(name = "versuch")
private Timestamp tryTime;
@Column(name = "versuch_anzahl")
private int tryAmount;
@Column(name = "status")
private int state;
@Column(name = "ip")
private char ip;
@ManyToOne
@MapsId("mb_id")
@JoinColumn(name = "id")
private MessageBody messageBody;
// getter + setter + hashcode + equals
}
The relation is bidirectional as in the question, but I put the Collection in the MessageBody-Domainclass. After some other fixes like the "AttributOverrides" it worked. Hope I could help another one with the solution!