0

This is my first play with hibernate/JPA2. I am getting "Unable to build EntityManagerFactory". Can you tell me where is the problem?

Here is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?><persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="pdfEx" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>iw.pdfEx.persistence.Pdf</class>
    <class>iw.pdfEx.persistence.XmlConversion</class>
    <properties>
        <property name="hibernate.connection.username" value="icite"/>
        <property name="hibernate.connection.password" value="${hpass}"/>
        <property name="hibernate.connection.url" value="${hurl}"/>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
    </properties>
</persistence-unit>

Here is my test class:

public class PersistenceTest {

private static EntityManagerFactory emf;
private static EntityManager em;
private static String randomPDFname;
private static String randomGITversion;
private static long sysTime = 0;

@BeforeClass
public static void createEntityManagerFactory() {
    Logger.getLogger(FileConverter.class.getName()).log(Level.INFO, "hibernate URL is "+System.getProperty("hurl"));           
    Logger.getLogger(FileConverter.class.getName()).log(Level.INFO, "the path to pdf2xml is "+System.getProperty("pdf2xml"));          
    emf = Persistence.createEntityManagerFactory("pdfEx");
    Logger.getLogger(FileConverter.class.getName()).log(Level.INFO, "PersistenceTest: EM factory created!");           
    randomPDFname = "random-pdf-name-"+UUID.randomUUID().toString();
    randomGITversion = "random-git-version-"+UUID.randomUUID().toString();
    sysTime = Math.round(System.currentTimeMillis()/((10^3)*3600));//systime in hours, rather than millisecs
}

@Before
public void beginTransaction() {
    em = (EntityManager) Persistence.createEntityManagerFactory("pdfEx").createEntityManager();
    em.getTransaction().begin();
}

@After
public void rollbackTransaction() {

    if (em.getTransaction().isActive())
        em.getTransaction().rollback();

    if (em.isOpen())
        em.close();
}

@AfterClass
public static void closeEntityManagerFactory() {
    emf.close();
}

@Test
public void dbTest() {
    //fail("Not yet implemented");
    Pdf testPdf = new Pdf();
    testPdf.setName(randomPDFname);
    testPdf.setSize(sysTime);       
    //check that testPDF is, indeed, not yet in the DB:
    Query getPDF = em.createNamedQuery("Pdf.Queries.PdfByNameAndSize");
    getPDF.setParameter("pdfname", testPdf.getName());
    getPDF.setParameter("pdfsize", testPdf.getSize());
    List foundPDFs = getPDF.getResultList();
    assertTrue("Random PDF "+randomPDFname+" is already in the DB", foundPDFs == null || foundPDFs.size() == 0 );
    //persist testPdf in the DB
    em.persist(testPdf);
    //em.flush();
    Logger.getLogger(FileConverter.class.getName()).log(Level.INFO, "Persisted testPdf");
    //retrieve testPdf from the DB
    Pdf thePDF = (Pdf) getPDF.getSingleResult();//trying to re-run the query
    //and use it as a reference in a new XmlConversion
    XmlConversion testXml = new XmlConversion();
    testXml.setGitVersion(randomGITversion);
    testXml.setPdf(thePDF);
    testXml.setXmlOutputSize(sysTime);
    //verify there is no such XmlConversion
    Query getXML = em.createNamedQuery("XmlConversion.Queries.XmlByPdfAndGit");
    getXML.setParameter("pdfname", testXml.getPdf());
    getXML.setParameter("gitversion", testXml.getGitVersion());
    List foundXMLs = getXML.getResultList();
    assertTrue("XmlConversion is already in the DB", foundXMLs == null || foundXMLs.size() == 0 );
    //store XmlConversion in the DB
    em.persist(testXml);
    //em.flush();
    //retrieve XmlConversion from the DB
    foundXMLs = getXML.getResultList();
    assertTrue("XmlConversion is not in the DB", foundXMLs.size() == 1);
    Logger.getLogger(FileConverter.class.getName()).log(Level.INFO, "PersistenceTest successful!");        
}

}

Here one of the persistable entities:

@Entity @NamedQuery(
    name="Pdf.Queries.PdfByNameAndSize",
    query="SELECT c FROM Pdf c WHERE c.name = :pdfname AND c.size = :pdfsize") @Table(name = "t_pdf") public class Pdf implements java.io.Serializable {    @Column(nullable=false)
private Integer id;
@Column(nullable=false)
private String name;
@Column(nullable=false)
private Long size;
private Set<XmlConversion> xmlConversions = new HashSet<XmlConversion>(0);

public Pdf() {
}

public Pdf(String name, Long size) {
    this.name = name;
    this.size = size;
}

public Pdf(String name, Long size, Set<XmlConversion> xmlConversions) {
    this.name = name;
    this.size = size;
    this.xmlConversions = xmlConversions;
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
    return this.id;
}

public void setId(Integer id) {
    this.id = id;
}

@Column(name = "name", nullable = false, length = 245)
public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

@Column(name = "size", nullable = false, length = 16777215)
public Long getSize() {
    return this.size;
}

public void setSize(Long size) {
    this.size = size;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pdf")
public Set<XmlConversion> getXmlConversions() {
    return this.xmlConversions;
}

public void setXmlConversions(Set<XmlConversion> xmlConversions) {
    this.xmlConversions = xmlConversions;
}

Here the other:

@Entity @NamedQuery(
    name="XmlConversion.Queries.XmlByPdfAndGit",
    query="SELECT c FROM XmlConversion c WHERE c.pdf = :pdfname AND c.gitVersion = :git" ) @Table(name = "t_xml_conversion") public class XmlConversion implements java.io.Serializable {

private Integer id;
private Pdf pdf;
private Long xmlOutputSize;
private String gitVersion;
private Integer durationMillisec;
private Date createdAt;

public XmlConversion() {
}

public XmlConversion(Pdf pdf, String gitVersion) {
    this.pdf = pdf;
    this.gitVersion = gitVersion;
}

public XmlConversion(Pdf pdf, Long xmlOutputSize, String gitVersion,
        Integer durationMillisec) {
    this.pdf = pdf;
    this.xmlOutputSize = xmlOutputSize;
    this.gitVersion = gitVersion;
    this.durationMillisec = durationMillisec;
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
    return this.id;
}

public void setId(Integer id) {
    this.id = id;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PDF_id", nullable = false)
public Pdf getPdf() {
    return this.pdf;
}

public void setPdf(Pdf pdf) {
    this.pdf = pdf;
}

@Column(name = "xml_output_size")
public Long getXmlOutputSize() {
    return this.xmlOutputSize;
}

public void setXmlOutputSize(Long xmlOutputSize) {
    this.xmlOutputSize = xmlOutputSize;
}

@Column(name = "git_version", nullable = false, length = 45)
public String getGitVersion() {
    return this.gitVersion;
}

public void setGitVersion(String gitVersion) {
    this.gitVersion = gitVersion;
}

@Column(name = "duration_millisec")
public Integer getDurationMillisec() {
    return this.durationMillisec;
}

@Column(name = "created_at", nullable = false, columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
public Date getCreatedAt() {
    return this.createdAt;
}

public void setDurationMillisec(Integer durationMillisec) {
    this.durationMillisec = durationMillisec;
}

Here are the maven dependencies:

  <dependencies>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.10</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.directory.studio</groupId>
    <artifactId>org.apache.commons.io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.25</version>
</dependency>
<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.0-api</artifactId>
    <version>1.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.2.3.Final</version>
    <scope>runtime</scope>
</dependency>

When I try "maven test" I am getting:

iw.pdfEx.PersistenceTest  Time elapsed: 3.156 sec  <<< ERROR! javax.persistence.PersistenceException: [PersistenceUnit: pdfEx] Unable to build EntityManagerFactory
at org.hibernate.property.BasicPropertyAccessor.createSetter(BasicPropertyAccessor.java:252)
at org.hibernate.property.BasicPropertyAccessor.getSetter(BasicPropertyAccessor.java:245)
at org.hibernate.mapping.Property.getSetter(Property.java:326)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertySetter(PojoEntityTuplizer.java:444)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:201)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:135)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:188)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:341)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:507)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:146)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:385)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:59)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
at iw.pdfEx.PersistenceTest.createEntityManagerFactory(PersistenceTest.java:42)

Here is the output from the test as I found it in the surefire report:

Jul 28, 2013 12:11:25 PM iw.pdfEx.PersistenceTest createEntityManagerFactory 
INFO: hibernate URL is jdbc:mysql://localhost:8600/icite Jul 28, 2013 12:11:25 PM iw.pdfEx.PersistenceTest createEntityManagerFactory
INFO: the path to pdf2xml is /home/nikolay/Documents/invoiceFairy/pdf2xml/pdftoxml.linux64.exe.1.2_7 Jul 28, 2013 12:11:26 PM org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.2.Final} Jul 28, 2013 12:11:26 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.2.3.Final} Jul 28, 2013 12:11:26 PM org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found Jul 28, 2013 12:11:26 PM org.hibernate.cfg.Environment buildBytecodeProvider    INFO: HHH000021: Bytecode provider name : javassist Jul 28, 2013 12:11:27 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure    INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!) Jul 28, 2013 12:11:27 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure    INFO: HHH000115: Hibernate connection pool size: 20 Jul 28, 2013 12:11:27 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: true Jul 28, 2013 12:11:27 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:8600/icite] Jul 28, 2013 12:11:27 PM org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {user=icite, password=****, autocommit=true, release_mode=auto} Jul 28, 2013 12:11:27 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect Jul 28, 2013 12:11:28 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory Jul 28, 2013 12:11:28 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
2
  • Make sure the stack trace is complete, and show us the code of your two entities. Commented Jul 28, 2013 at 14:16
  • Just added the code of the entities and the output of the test Commented Jul 28, 2013 at 15:15

1 Answer 1

1

You don't have any setter method defined for the property createdAt of XmlConversion.

Sign up to request clarification or add additional context in comments.

4 Comments

You are right - when I added the method the EM factory was created. I am getting a different error message (I will have a look at it now) but the original bug was eliminated. I did not add a setter method because this is thought as a timestamp field and I would like to set it at the DB level. I did not realise that this is causing a problem as it changes the signature of the class. Shame the error message is so unspecific. Thank you very much!
Since you annotated the getters and not the fields, Hibernate uses the setters to populate your entities. If it doesn't have a setter, it can't populate the property. You can make the setter protected or package-protected, or even private IIRC.
Do you mean that if I annotated the fields (rather than the getter methods) the problem would not have arisen even if the setter method was omitted?
Yes. Because in that case, Hibernate would use field access type instead of property access type: it would populate the fields directly, without going through the setters. Another way is to use the @Access JPA annotation. Make sure to have annotations ONLY on fields if you use that (mixing annotated fields and annotated methods won't work: one of the locations will be ignored). Also, access type will be field also when reading fields to write them in the database. Not only when writing them with values coming from the database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.