在执行以下操作org.hibernate.LazyInitializationException时,当我尝试访问延迟加载的异常时遇到错误:
@Transactional
public void displayAddresses()
{
Person person = getPersonByID(1234);
List<Address> addresses = person.getAddresses(); // Exception Thrown Here
for(Address address : addresses)
System.out.println(address.getFullAddress());
}
Run Code Online (Sandbox Code Playgroud)
我的实体看起来像这样:
@Entity
@Table("PERSON_TBL")
public class Person
{
...
@OneToMany(cascade=CascadeType.ALL, targetEntity=Address.class, mappedBy="person")
private List<Address> addresses;
...
}
@Entity
@Table("ADDRESS_TBL")
public class Address
{
...
@ManyToOne(targetEntity=Person.class)
@JoinColumn(name="PERSON_ID", referencedColumnName="PERSON_ID")
Person person;
...
}
Run Code Online (Sandbox Code Playgroud)
我的印象是,通过在我的displayAddresses()方法中使用@Transactional批注,它将使会话保持活动状态,直到该方法完成为止,从而使我可以访问延迟加载的Address集合。
我想念什么吗?
编辑
按照Tomasz的建议:在我的displayAddresses()方法中,状态TransactionSynchronizationManager.isActualTransactionActive(),变为false。
这确实可以缩小问题的范围,但是为什么此时我的交易不能处于活动状态?
我正在浏览用于文件和目录管理操作的 Win32 API 函数。我看到其中一些功能有其所谓的“事务”对应项。
示例:
CreateDirectory和CreateDirectoryTransacted
RemoveDirectory和RemoveDirectoryTransacted
CreateFile和CreateFileTransacted
CopyFile和CopyFileTransacted
我阅读了这些事务函数的解释、维基百科文章Transactional NTFS和此 MSDN 杂志页面。但由于这些页面中的术语(对我来说)很重,我并没有清楚地理解这些解释。他们都达成了一个共同的共识:这些函数是“原子的”。但据我对“原子”这个词的理解,它是一个原子核,周围有旋转的电子......
您能用基本、简单的英语句子解释一下,这些函数的用途和操作是什么?人们为什么以及何时会选择 API 函数的事务版本?
我是 EJB 项目的新手。并且我试图了解在@Transactional我的 EJB 方法顶部使用注释。我搜索了内容,对此没有明确的解释。任何人都可以清楚地解释这一点。
我希望能够验证每个工作单元是在自己的事务中完成的,还是作为单个全局事务的一部分完成的.
我有一个方法(使用spring和hibernate定义),其形式如下:
private void updateUser() {
updateSomething();
updateSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)
这是从两个地方调用的,用户登录时的网站和每天运行的批处理作业.对于Web服务器上下文,它将与Web服务器创建的事务一起运行.对于批处理作业,每个用户必须有一个事务,因此如果在此方法期间出现故障,则回滚事务.所以我们有两种方法:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
updateUser();
}
@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
updateUser();
}
Run Code Online (Sandbox Code Playgroud)
从批处理作业调用updateUserCreateNewTransaction(),并从Web服务器上下文调用updateUserWithExistingTransaction().
这有效.但是,(批量)的这种行为不能改变是非常重要的,所以我希望创建一个测试这种行为的测试.如果可能的话,我想在不更改代码的情况下这样做.
所以对我开放的一些选择是:
计算批处理作业运行期间在数据库中打开的事务.
在updateSomethingElse()方法中以某种子替换方式更改数据,以便至少一个用户更新失败,并检查该用户的updateSomething()是否未发生.
代码审查.
1是一个非常依赖于数据库的方法,我如何保证hibernate不会创建事务呢?2似乎更好,但设置起来非常复杂.3并不真实,因为我们需要为每个版本做一个.
那么,有没有人有一种方法可以让我测试这段代码,最好是通过系统测试或集成测试?
我正在编写尝试并开始讨论Spring Unit测试,特别是Transactional单元测试.
我们目前在各种类中注释了大约441个测试,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration
@ContextConfiguration(locations={"/context/ServiceTest-context.xml"}, inheritLocations=false)
public class ServiceTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
public void testSomething() {}
@Test
public void testSomethingElse() {}
}
Run Code Online (Sandbox Code Playgroud)
我们的每个测试类都有自己的测试上下文.
我们面临的问题是,当我们运行单个测试类或单个包时,测试运行正常.
但是,当我们想通过使用maven或类似Hudson集成之类的东西来扩展它以运行所有我们的测试(当前> 400).
mvn test
Run Code Online (Sandbox Code Playgroud)
我们达到了一个点,然后开始体验Java GC Limit超出错误.
现在我觉得这取决于我们的测试计划设计,而不是我们需要提高内存限制或关闭警告.
任何人都可以分享他们的经验以及他们解决类似问题的方式吗?
Eggsy
spring garbage-collection maven-2 unit-testing transactional
我有一个@Transactional JUnit测试设置,我想将一些测试数据保存到数据库,并测试关联是否正确.但是,在测试关联时,它们总是评估为null,即使它在非事务性测试中有效.
我使用@Before注释保留两个对象:
@Before
public void testData() {
TestObjectOne o = new TestObjectOne();
o.setName("One");
repo.saveEntity(o); //autowired
TestObjectTwo t = new TestObjectTwo();
t.setOne(o);
t.setName("Two");
repo.saveEntity(t);
}
Run Code Online (Sandbox Code Playgroud)
在测试中访问这两个对象时,我得到了正确的实例:
TestObjectOne o = repo.getOneByName("One");
TestObjectOne t = repo.getTwoByName("Two");
Run Code Online (Sandbox Code Playgroud)
当检查t和之间的关联时o,我得到了正确的引用,因为我明确定义了该关联:
Assert.assertNotNull(t.getOne());
Run Code Online (Sandbox Code Playgroud)
但是当反过来检查时,对象o没有正确更新:
Assert.assertNotNull(o.getTwos());
Run Code Online (Sandbox Code Playgroud)
该关联在域对象中定义为
在One:
@OneToMany(mappedBy = "one", fetch = FetchType.EAGER)
private List<Two> twos;
Run Code Online (Sandbox Code Playgroud)
在Two:
@ManyToOne(optional = false)
private One one;
Run Code Online (Sandbox Code Playgroud)
当我没有以@Transactional运行测试时,它运行得很好.
编辑 保存测试中的实体而不是@Before方法,没有任何区别.
我正在研究spring框架并尝试在我的项目中使用它.但是我在我的服务中使用了spring数据存储库和@Transactional注释时遇到了以下问题.问题是弹簧启动没有例外.稍后当我尝试访问spring数据存储库时,我得到NullPointerException.也许你有一些想法可以帮助我.
我使用spring数据库定义如下:
package net.question.data.repository;
import net.question.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个定义的服务,其中包含自动装配的存储库:
package net.question.data.service;
import net.question.data.repository.UserRepository;
import net.question.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserService {
@Autowired
public UserRepository userRepository;
public void doStuff(User usr) {
// login will be here
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试以显示我的问题:
package net.question.spring;
import static org.junit.Assert.assertNotNull;
import net.question.data.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/app-context.xml")
public class InjectionTestSuite {
@Autowired
UserService userService;
@Test
public …Run Code Online (Sandbox Code Playgroud) repository transactional nullpointerexception autowired spring-data
这个问题的核心是:是否可以通过Spring关闭钩子触发的方法执行事务?
目前,我有一个HyperSmartDbServer类,该类实现了SmartLifeCycle,如以下问题所示: 在spring bean中,可以有一个可以使用事务的shutdown方法吗?
我在该类中有一个标记为事务的方法,该方法作为stop方法的一部分被调用:
@Transactional
public void executeShutdown() {
hsqlDBShutdownService.executeShutdownQuery();
hsqlDBShutdownService.closeEntityManager();
}
Run Code Online (Sandbox Code Playgroud)
该方法中使用的服务有点麻烦,因为我无法在EntityManager中自动连线到此类:
@Service
public class HsqlDBShutdownService {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private HyperSqlDbServer hyperSqlDbServer;
@Transactional
public void executeShutdownQuery() {
entityManager.createNativeQuery("SHUTDOWN").executeUpdate();
}
@Transactional
public void closeEntityManager() {
entityManager.close();
}
@PostConstruct
public void setHsqlDBShutdownService() {
hyperSqlDbServer.setShutdownService(this);
}
}
Run Code Online (Sandbox Code Playgroud)
您可能会注意到,我真正想完成的一切只是在停止服务器之前调用查询“ SHUTDOWN”。如果不这样做,则hsqldb锁定文件会在服务器重新启动时停留,并且服务器会引发异常。
上面的代码产生以下异常:
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)
...
Run Code Online (Sandbox Code Playgroud)
所以我的原始问题仍然存在,但是如果有人对如何以另一种方式执行该查询有想法,我也会尝试一下。
仅供参考,我也尝试了@PreDestroy批注,但得到了相同的TransactionRequiredException。
编辑:为了完整起见,我在整个项目中都使用JpaTransactionManager和@Transactional批注,但关机时除外...
编辑2:数据源和事务管理器配置:
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:persistence.properties")
public class PersistenceConfig implements TransactionManagementConfigurer {
private static final String PASSWORD_PROPERTY = "dataSource.password"; …Run Code Online (Sandbox Code Playgroud) 我对这个问题进行了一些研究:我删除了一个过渡电子邮件模板,现在又一次又一次出现此错误:
Invalid transactional email code: 4
Run Code Online (Sandbox Code Playgroud)
是的,我知道,“ 4”是模板的ID。我制作了一个虚拟模板,并将数据库中的ID更改为4,但是我不希望该虚拟对象。
有谁能告诉我如何解决这个问题?也许有点重置交易电子邮件?
提前感谢
我正在阅读有关在何处放置Transactional(接口与实现)的信息:
Spring团队的建议是您仅使用@Transactional注释对具体的类进行注释,而不是对接口进行注释。您当然可以在接口(或接口方法)上放置@Transactional批注,但这仅在您使用基于接口的代理时才可以按预期使用。注解未继承的事实意味着,如果您使用的是基于类的代理,则基于类的代理基础结构将无法识别事务设置,并且该对象也不会包装在事务性代理中(这肯定是不好的) 。因此,请听取Spring团队的建议,仅使用@Transactional批注对具体类(以及具体类的方法)进行批注。
所以问题是,到底什么是基于接口的代理,如何查看它是否被使用?是一些配置还是实例化/使用实例的方式?
transactional ×10
spring ×6
java ×2
associations ×1
autowired ×1
database ×1
ejb ×1
email ×1
file-io ×1
hibernate ×1
hsqldb ×1
jpa ×1
junit ×1
magento ×1
maven-2 ×1
ntfs ×1
php ×1
proxy ×1
repository ×1
shutdown ×1
spring-data ×1
spring-jdbc ×1
unit-testing ×1
winapi ×1