1

I am new to JPA and I am developing software with JPA 2.1.

It creates the tables, run the code to save, does not appear any error with the JPA or Hibernate and when I read the same saved object, it is null

My persistence.xml

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="CLFockinkPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>br.ind.fockink.model.Cliente</class>
    <class>br.ind.fockink.model.Funcionario</class>
    <class>br.ind.fockink.model.Licenca</class>
    <class>br.ind.fockink.model.PreCliente</class>
    <class>br.ind.fockink.model.Terceiro</class>
    <class>br.ind.fockink.model.Usuario</class>
    <properties>
        <!--  propriedades do hibernate -->
        <!-- Hibernate properties -->
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        <property name="hibernate.hbm2ddl.auto" value="create-drop" />

        <!--  atualiza o banco, gera as tabelas se for preciso -->
        <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@xxxxxxxxx:1521:XE"/>
        <property name="javax.persistence.jdbc.user" value="sys as sysdba"/>
        <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
        <property name="javax.persistence.jdbc.password" value="xxxxx"/>


    </properties>
</persistence-unit>

My Class:

public class PreCliente implements Serializable {

  private static final long serialVersionUID = 1L;
  // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
  @Id
  @Basic(optional = false)
  @SequenceGenerator(name = "WEB_SEQGRA2", sequenceName = "WEB_SEQGRA2", allocationSize = 1)
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "WEB_SEQGRA2")
  @Column(name = "ID_PRE_CLIENTE")
  private Long idPreCliente;
  @Column(name = "CPF")
  private String cpf;
  @Column(name = "CNPJ")
  private String cnpj;
  @Column(name = "RAZAO_SOCIAL")
  private String razaoSocial;
  @Basic(optional = false)
  @Column(name = "NOME_SOBRENOME")
  private String nomeSobrenome;

Generic DAO for persist:

public class GenericDAO<PK, T> {
  private EntityManager entityManager;

  public GenericDAO(EntityManager entityManager) {
      this.entityManager = entityManager;
  }

  public T getById(PK pk) {
      return (T) entityManager.find(getTypeClass(), pk);
  }

  public void save(T entity) {
      entityManager.persist(entity);
  }

  public void update(T entity) {
      entityManager.merge(entity);
  }

  public void delete(T entity) {
      entityManager.remove(entity);
  }

  public List<T> findAll() {
      return entityManager.createQuery(("FROM " + getTypeClass().getName()))
              .getResultList();
  }

  private Class<?> getTypeClass() {
      Class<?> clazz = (Class<?>) ((ParameterizedType) this.getClass()
              .getGenericSuperclass()).getActualTypeArguments()[1];
      return clazz;
  }

DAO Extend GenericDAO:

public class PreClienteDAO extends GenericDAO<Long, PreCliente> {

  public PreClienteDAO(EntityManager entityManager) {
      super(entityManager);
  }

And my test:

public static void main(String[] args) {
    // TODO code application logic here
    PreCliente pc = new PreCliente();
    pc.setCpf("123456789");
    pc.setNomeSobrenome("teste");
    PreClienteDAO dao = new PreClienteDAO(JPAUtil.getEntityManager());
    dao.save(pc);

    List<PreCliente> test = dao.findAll();
    System.out.println(test.get(0));
}

Finaly, the hibernate return:

Hibernate: 
create table PreCliente (
    ID_PRE_CLIENTE number(19,0) not null,
    CNPJ varchar2(255 char),
    CPF varchar2(255 char)
    NOME_SOBRENOME varchar2(255 char) not null,
    RAZAO_SOCIAL varchar2(255 char),
    primary key (ID_PRE_CLIENTE)
)
Hibernate: 
create sequence WEB_SEQGRA2
Hibernate: 
select
    WEB_SEQGRA2.nextval 
from
    dual
Hibernate: 
select
    precliente0_.ID_PRE_CLIENTE as ID_PRE_CLIENTE1_3_,
    precliente0_.CNPJ as CNPJ2_3_,
    precliente0_.CPF as CPF3_3_,
    precliente0_.NOME_SOBRENOME as NOME_SOBRENOME4_3_,
    precliente0_.RAZAO_SOCIAL as RAZAO_SOCIAL5_3_ 
from
    PreCliente precliente0_

And the error for return anything:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:638)
at java.util.ArrayList.get(ArrayList.java:414)
at br.ind.fockink.clfockink.main(clfockink.java:31)  

Looking at the return of hibernate it seems that he is not saving the object correctly, but why?

3 Answers3

4

When running in non-managed environment, you have to open, commit and rollback the transaction by yourself, like:

try {
   tx = em.getTransaction();
   tx.begin();

   // do some work
   ...

   tx.commit();
}
catch (RuntimeException e) {
    if ( tx != null && tx.isActive() ) tx.rollback();
    throw e; // or display error message
}
finally {
    em.close();
}

More info here.

Szarpul
  • 1,531
  • 11
  • 21
  • Thank you, that part was really missing and still did downgrade to JPA 2.0 and then everything was fine! Created the table and inserted data! – Paulo H. Hartmann May 08 '15 at 16:48
0

Put

entityManager.flush();
after entityManager.persist(), because entityManager.flush() operation can be used to force writing all changes to the database before the transaction is committed, depending on how the EntityManager (FlushModeType, to be more specific) is configured.

You can use this link to read more about it:

What does EntityManager.flush do and why do I need to use it?

Community
  • 1
  • 1
Raphael Amoedo
  • 4,233
  • 4
  • 28
  • 37
  • He is not creating any table at least manually checked in the database, there is nothing. And thank you for the .flush() I did not know. – Paulo H. Hartmann May 08 '15 at 14:49
  • Are you logged on the as the same user that application uses? (sys as sysdba)... And may I suggest to create a user to do that. – Raphael Amoedo May 08 '15 at 14:54
  • And it will have nothing on database because you're setting hibernate.hbm2ddl.auto as create-drop. So when SessionFactory is closed, database schema will be dropped. Try changing to create. – Raphael Amoedo May 08 '15 at 14:56
-3

Do you not need to select something in this query?

public List<T> findAll() {
    return entityManager.createQuery(("FROM " + getTypeClass().getName()))
          .getResultList();
}

"SELECT * FROM " ...

George
  • 903
  • 4
  • 19