【发布时间】:2015-10-28 09:17:31
【问题描述】:
我使用 hibernate-jpa-2.1-api
我有一个用于业务逻辑的 EJB 类
我做了一个@RequestScopded EntityManager,它被注入到EJB中并在save方法中调用,没有错误,但在数据库中甚至没有条目。有趣的是,在数据库中正确增加了休眠序列号但没有调用实体的插入,我什至在日志中都没有看到实体的插入语句。
如果我打电话
em.flush()
之后
em.persist()
我收到一条错误消息,表明没有正在进行的交易。
我有其他实体的其他保存方法以相同的方式组织并且工作正常。我还尝试将 EntityManager 作为@PersistenceContect 注入到 EJB 中,在这种情况下它可以工作,但我想知道为什么在这种特定情况下,requesed scoped EM 不起作用,而在其他情况下它确实起作用。
这是我的代码:
1.) 实体
@Entity
@Table(name = "CONSULTATION")
public class Consultation implements java.io.Serializable {
private static final long serialVersionUID = 2989793280017282405L;
private long idConsulation;
private DomainExpert domainExpert;
private Date date;
private Long hours;
private String description;
private PayedResource payedResource;
private Integer version;
public Consultation() {
}
public Consultation(long idConsulation, DomainExpert domainExpert) {
this.idConsulation = idConsulation;
this.domainExpert = domainExpert;
}
public Consultation(long idConsulation, DomainExpert domainExpert, Date date, Long hours) {
this.idConsulation = idConsulation;
this.domainExpert = domainExpert;
this.date = date;
this.hours = hours;
}
@Id
@TableGenerator(name = "ID_CONSULATION", table = "hibernate_sequence", pkColumnName = "SEQUENCE_NAME", valueColumnName = "NEXT_VAL", pkColumnValue = "SEQ_ID_CONSULATION", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_CONSULATION")
@Column(name = "ID_CONSULATION", unique = true, nullable = false)
public long getIdConsulation() {
return this.idConsulation;
}
public void setIdConsulation(long idConsulation) {
this.idConsulation = idConsulation;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_DOMAIN_EXPERT", nullable = false)
public DomainExpert getDomainExpert() {
return this.domainExpert;
}
public void setDomainExpert(DomainExpert domainExpert) {
this.domainExpert = domainExpert;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATE", length = 19, nullable = false)
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
@Column(name = "HOURS", length = 20, nullable = false)
public Long getHours() {
return this.hours;
}
public void setHours(Long hours) {
this.hours = hours;
}
@Column(name = "DESCRIPTION", length = 500)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Version
@Column(name = "VERSION", nullable = false)
public Integer getVersion() {
return this.version;
}
public void setVersion(Integer version) {
this.version = version;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_PAYED_RESOURCE", nullable = false)
public PayedResource getPayedResource() {
return this.payedResource;
}
public void setPayedResource(PayedResource payedResource) {
this.payedResource = payedResource;
}
}
2.) EJB
@Stateless
public class DomainExpertHandler {
@Inject
private EntityManager em;
public void saveConsultation(Consultation consultation) {
if (consultation.getIdConsulation() > 0) {
em.merge(consultation);
} else {
em.persist(consultation);
}
}
}
3.) 生成 @requestscoped EM 的 bean
public class Resources {
@PersistenceUnit
EntityManagerFactory emf;
@Produces
@RequestScoped
public EntityManager createEntityManager() {
return emf.createEntityManager();
}
protected void closeEntityManager(@Disposes EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
}
4.) 我的 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="cloudflow" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:jboss/datasources/cloudflow</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.jdbc.batch_size" value="50"/>
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
</properties>
</persistence-unit>
</persistence>
【问题讨论】:
-
你是否尝试在保存方法上方添加
@TransactionAttribute(TransactionAttributeType.REQUIRED)? -
@Gab 是的,我已经尝试过,但遇到了同样的问题……看起来没有交易,或者 em 在那一刻没有与交易相关联
-
我没有看到您在手动创建的 EntityManager 上实际启动或提交事务。很可能您应该让容器将容器管理的 EntityManager 注入您的生产者类,而不是 EntityManagerFactory。
-
@Gimby 我在这里使用了请求范围 EM piotrnowicki.com/2012/11/… 的示例,它在其他 bean 中正常工作,但这个似乎有一些问题
-
@simonC 您是否阅读了链接中关于您的问题的文字?
Notice the BeanA being a non-transactional resource. Also note that we injected and invoked some operation on the EntityManager (this makes the injection to be actually performed.) Now if the BeanB is transactional and also injects and uses EntityManager – we’ll end with a non-transactional EntityManager that will not throw any exception and will not save any changes to the database.其中BeanA是您的DomainExpertHandler
标签: hibernate jpa transactions ejb