4

I'm trying to save entity to DB using jpa. Here is my Entity:

import javax.persistence.*;

@Entity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    public Book() {
    }
    public Book(String title) {
        this.title = title;
    }
    public Long getId() {
        return id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}

Here persistence.xml:

<persistence-unit name="bookUnit">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>ee.jpa.Book</class>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Lessons"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
        <property name="javax.persistence.jdbc.password" value="1"/>
    </properties>
</persistence-unit>

Here is my EJB:

@Stateless
public class JpaBean {
    @PersistenceContext
    EntityManager entityManager;
    public long saveBook(Book book) {
        entityManager.persist(book);
        return book.getId();
    }
}

Here is my servlet:

@WebServlet("/jpaExample")
public class ServletExample extends HttpServlet {
    @EJB
    JpaBean jpaBean;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Book book = new Book("servlet");
        long l = jpaBean.saveBook(book);
        resp.getWriter().write(l + " ");
    }
}

I've added EclipseLink.jar to my project and to TomcatEEDir/lib/ directory. Everything compiles and run with no exception. I get different numbers each time I run servlet, like 1 2 3.... etc. But when I look at db there nothing there. No table, no data. What I did wrong? How to fix it? Also I tried to use java SE, for this I added transaction-type="RESOURCE_LOCAL" to persistence-unit. And wrote code like this:

public class MainExample {
public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("bookUnit");
    EntityManager em = emf.createEntityManager();
    Book book = new Book("main");
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    em.persist(book);
    tx.commit();
    em.close();
    emf.close();
}
}

This code works perfectly and saves data to DB. So, what is wrong with my previous code. Why nothing saves to DB?

Edit: Same result if using Hibernate.

user769552
  • 179
  • 1
  • 3
  • 10
  • This would appear to be an issue with transactions as hinted at below. Can you try adding `@TransactionAttribute(TransactionAttributeType.REQUIRED)` rather than `@Transactional` as the latter AFAIK (and I am not overly familiar with EJB) is for use with CDI beans. See: http://stackoverflow.com/questions/17838221/jee7-do-ejb-and-cdi-beans-support-container-managed-transactions – Alan Hay Apr 20 '17 at 18:22
  • I tried add @Transactional and @TransactionAttribute(TransactionAttributeType.REQUIRED) Nothing changed. – user769552 Apr 20 '17 at 19:11
  • hi did you ever find a solution to this problem? – qualebs Jul 08 '17 at 20:00

2 Answers2

0

I think you should call .flush() so they are being saved. Try that I think it will work. also use

@Transactional
public long saveBook(Book book) {
    entityManager.persist(book);
    entityManager.flush();
    return book.getId();
}
strash
  • 1,291
  • 2
  • 15
  • 29
  • I've tried to write entityManager.flush(); but it didn't help. And as I understand JTA should create transaction before starting EJB method, and commit it after, so all changes should be committed to DB with no additional code. – user769552 Apr 20 '17 at 17:34
  • btw your code is telling me that this number that you have - the id of the saved book has absolutely nothing in connection with the persist. it will be returned even if you have no enetitymanager.persist – strash Apr 20 '17 at 17:37
  • try using @Transactional on your method anyway – strash Apr 20 '17 at 17:39
  • and I hope you have the table created in your database right? – strash Apr 20 '17 at 17:40
  • I've tried @Transaction, didn't help, as I know EJB is transactional without this annotation, I can use it to make transactional e.g. servlet, but not EJB, couse it transactional by default. Yes I have created table in db. When I run SE main method it created and there one row with data id = 1 and title = main. But when I run EE example it doesn't add data to DB. BTW when I run main method it creates also SEQUENCE table in db . – user769552 Apr 20 '17 at 17:47
  • MySQL supports auto-increment PK columns so you do not need a sequence table. I am not overly familar with EclipseLink but if you try adding `@GeneratedValue(strategy=GenerationType.IDENTITY)` then it should create the table with an auto-increment PK column rather than using a separate sequence table. – Alan Hay Apr 20 '17 at 18:32
  • did you ever find a solution to this problem? – qualebs Jul 08 '17 at 19:59
0

I have done the same project with the aid of your lesson. However, I used a HibernatePersistenceProvider and the WildFly server. I had encountered the following problems and found some solutions. Maybe something will help you.

  1. When I added a hibernate-core dependency, I didn't use scope=provided, but I should have.

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.2.17.Final</version>
        <scope>provided</scope>
    </dependency>
    
  2. The persistence.xml location is WEB-INF->classes->META-INF. I had failed my app, while I didn't correct this one.

This is a link to my project on GitHub.