0

I have two tables (command and commandLine), i want to write in both when i insert a new command Here is my Command Object, I use a OneToMany to map with the object CommandLine

@Entity
@Table(name = "t_commands")
public class Command {

    @Id @Getter
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idCommand;

    @Getter @Setter
    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name = "idUser", nullable = false)
    private User user;

    @Getter @Setter
    @Column(name = "commandDate")
    private String date;

    @Getter @Setter
    @OneToMany(targetEntity = CommandLine.class, mappedBy = "idCommand")
    private List<CommandLine> lines = new ArrayList<>();

    public Command(User user, String date) {
        this.user = user;
        this.date = date;
    }

    public Command() {
    }

and my CommandLine object, I use ManyToOne to map with the object Command

@Entity
@Table(name = "t_commandlines")
public class CommandLine {

    @Id @Getter
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idCommandLine;

    @Getter
    @ManyToOne(targetEntity = Command.class, cascade = CascadeType.ALL)
    @JoinColumn(name = "idCommand", nullable = false)
    private Command idCommand;

    @Getter @Setter
    @ManyToOne(targetEntity = Article.class)
    @JoinColumn(name = "idArticle", nullable = false)
    private Article article;

    @Getter @Setter
    private int quantity;


    public CommandLine(Article article, int quantity) {
        this.article = article;
        this.quantity = quantity;
    }

and my CommandDAO

public class CommandDAO implements IDao<Command> {

    @Override
    public boolean create(Command object) {
        connect().persist(object);
        return true;
    }
}

I use interface

public interface IDao<T> {

    default EntityManager connect() {
        EntityManagerFactory entityManagerFactory;
        EntityManager entityManager;

        entityManagerFactory = Persistence.createEntityManagerFactory("webstore");
        entityManager = entityManagerFactory.createEntityManager();

        return entityManager;
    }

    default T read(Long id){return null;}
    default List<T> getAll() {return null;}
    default boolean create(T object) {return false;}
    default boolean update(T object) {return false;}
    default boolean delete(T object) {return false;}
    default Long getCount() {return 1L;}
}

I have no error, but nothing is writing in my db, I have no problem to retrieve data from the db with this structure, but impossible to write

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
rachidj
  • 5
  • 1

1 Answers1

0

It's not applying the changes because there is no transaction and so the persist operation is not flushed to the database.

Here a simplified example of what the code should look like:

public class CommandDAO implements IDao<Command> {

    @Override
    public boolean create(Command object) {
        EntityManager em = connect();
        try {
          em.getTransaction().begin();
          em.persist(object);
          em.getTransaction().commit();
          return true;
        }
        finally {
          em.close();
        }
    }
}

Also, there is no reason to create the EntityManagerFactory every time connect() is called. The creation of the factory is quite heavy but the factory is thread safe, you can reuse it when you need it. It makes sense to create an EntityManager every time you need it, but you have to close it when you are done with it.

Davide
  • 3,443
  • 1
  • 11
  • 18
  • Thank you also for your advise, where is the good place to create EntityManagerFactory ? – rachidj Mar 17 '21 at 11:31
  • It depends, but usually the factory is created by a different object when the application starts and then, when you need it, you can get an already created factory from there without having to call `Persistence.createEntityManagerFactory` every time. – Davide Mar 17 '21 at 13:11
  • If you are deploying your application on a application server, it usually creates the factory at start up – Davide Mar 17 '21 at 13:13
  • in my case, I use a simple example of servlets, JSP and JPA, I enter to my application within ServletLogin.java, should I put the factory in this servlet? thank for your time – rachidj Mar 17 '21 at 13:47
  • 1
    it's okay, i find this way https://stackoverflow.com/questions/7862700/best-practice-to-get-entitymanagerfactory very good practice – rachidj Mar 17 '21 at 14:12