EJB и JPA - постоянный объект с несколькими EJB

1

Я активно изучаю JPA и EJB, и я пришел к следующей ситуации: у меня есть один EJB (называемый SecondController), который реализует метод для сохранения сущности. Позвольте назвать его SecondEntity. Существует требование, чтобы, когда объект сохраняется, его поле dateInserted устанавливается на текущую дату (на практике требования могут быть более сложными - я хочу знать, является ли концепция в порядке или если я пойду полностью в неправильном направлении).

Теперь я определяю новый объект - позволю ему FirstEntity который содержит SecondEntity как атрибут. Я реализую еще один EJB, который реализует метод для сохранения FirstEntity - поэтому каждый раз, когда FirstEntity сохраняется, SecondEntity также сохраняется. Я знаю, что могу использовать @ManyToOne(optional = false, cascade = CascadeType.PERSIST) на secondEntity атрибута в FirstEntity (что будет делать автоматически сохраняются). Но помните, что есть требование dateInserted и логика уже реализована. Идея состоит в том, чтобы повторно использовать уже реализованный метод для сохранения SecondEntity в SecondController, введя его в FirstController.

@Entity
public class SecondEntity implements Serializable
{
}

@Entity 
public class FirstEntity implements Serializable
{
    @JoinColumn(name = "second_id", referencedColumnName = "second_id")
    @ManyToOne(optional = false)
    private SecondEntity secondEntity;
}

@Stateless
public class SecondController implements Serializable
{
    @PersistenceUnit(name = "PU")
    private EntityManagerFactory emf;

    public SecondController()
    {
    }

    public void create(SecondEntity secondEntity)
    {
        EntityManager em = emf.createEntityManager();

        try
        {
            secondEntity.setDateInserted(new Date(System.currentTimeMillis()));
            em.persist(secondEntity);
        }

        finally
        {
            em.close();
        }
    }
}

@Stateless
public class FirstController implements Serializable
{
    @PersistenceUnit(name = "PU")
    private EntityManagerFactory emf;

    @EJB
    private SecondController secondController;

    public FirstController()
    {
    }


    public void create(FirstEntity firstEntity)
    {
        EntityManager em = emf.createEntityManager();

        try
        {
            secondController.create(firstEntity.getSecondEntity());
            em.persist(firstEntity);
        }

        finally
        {
            em.close();
        }
    }
}

Точка примерного кода выше - вызов secondController.create(firstEntity.getSecondEntity()). Это нормально или считается плохой практикой? У меня есть два таких случая в моем приложении, и один работает (SecondEntity является необязательным - может быть null), а тот, который не имеет значения (SecondEntity является обязательным - не может быть null). Код не работает в em.persist(firstEntity), говоря:

java.lang.IllegalStateException: во время синхронизации новый объект был найден через отношение, которое не было отмечено каскадом PERSIST

Если я заменю упомянутый вызов на em.persist(firstEntity.getSecondEntity) код работает нормально.

Как я могу решить эту проблему?

Теги:
jpa
entitymanager
ejb

1 ответ

0
Лучший ответ

Вы не должны устанавливать поле dateInserted в своем EJB. Сделайте это в случае с событием PrePersist. Таким образом, поставщик персистентности будет уверен, что ваш крючок всегда вызывается автоматически перед сохранением объекта. Затем вы можете позволить persist быть каскадом от родительского объекта к другому (@ManyToOne(optional = false, cascade = CascadeType.PERSIST)).

@Entity
public class SecondEntity implements Serializable {
    @PrePersist
    public void prePersist() {
        if (dateInserted == null) {
            dateInserted = new Date();
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню