我正在尝试将Repository支持添加到Eclipselink JPA Spring项目中。 Eclipselink需要LoadTimeWeaving - 即使这不是绝对正确的,我后来也想让Aspects工作。
生产应用程序在Tomcat下运行,如果我已经完成并且没有尝试创建JUnit,我现在可能已经完成了。我有一种感觉,也许我真正拥有的是一个Eciplse(STS 3.4)问题,因为它似乎忽略了我的替代类加载器。但这似乎是基本的,这必须奏效,而且我做错了。
我只使用Annotations和Java配置。以下相关代码。
配置
@Configuration
@Profile("data")
@EnableJpaRepositories(basePackages="com.xxx.ieexb.repository",transactionManagerRef="transactionManager",entityManagerFactoryRef="entityManagerFactory")
@ComponentScan(basePackages= {"com.xxx.ieexb.jpa"
,"com.xxx.ieexb.repository"})
@EnableTransactionManagement
@EnableLoadTimeWeaving
@ImportResource("classpath:/properties-config.xml")
public class IeexbDataContextConfig {
@Value("#{ieexbProperties['com.xxx.ieexb.dataSource.Url']}")
public String dataSourceUrl;
@Value("#{ieexbProperties['com.xxx.ieexb.dataSource.Username']}")
public String dataSourceUsername;
@Value("#{ieexbProperties['com.xxx.ieexb.dataSource.Password']}")
public String dataSourcePassword;
@Value("#{ieexbProperties['com.xxx.ieexb.persistenceUnitName']}")
public String persistenceUnitName;
@Autowired
EntityManagerFactory entityManagerFactory;
@Bean()
public DriverManagerDataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.springframework.jdbc.datasource.DriverManagerDataSource");
dataSource.setUrl(dataSourceUrl);
dataSource.setUsername(dataSourceUsername);
dataSource.setPassword(dataSourcePassword);
return dataSource;
}
@Bean()
EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter() {
EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
eclipseLinkJpaVendorAdapter.setShowSql(true);
eclipseLinkJpaVendorAdapter.setGenerateDdl(false);
eclipseLinkJpaVendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.OraclePlatform");
return eclipseLinkJpaVendorAdapter;
}
@Bean()
EclipseLinkJpaDialect jpaDialect() {
EclipseLinkJpaDialect jpaDialect = new EclipseLinkJpaDialect();
return jpaDialect;
}
@Bean()
public FactoryBean<EntityManagerFactory> entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
//TODO Does this @Configuration do away with need for persistence.xml?
//emf.setPersistenceXmlLocation("classpath:persistence.xml");
emf.setPersistenceUnitName(persistenceUnitName);
emf.setDataSource(dataSource());
emf.setLoadTimeWeaver(loadTimeWeaver());
emf.setJpaDialect(new EclipseLinkJpaDialect());
emf.setJpaVendorAdapter(eclipseLinkJpaVendorAdapter());
//emf.setPersistenceProvider(persistenceProvider());
return emf;
}
@Bean()
public LoadTimeWeaver loadTimeWeaver() {
LoadTimeWeaver loadTimeWeaver = new ReflectiveLoadTimeWeaver();
return loadTimeWeaver;
}
}
死亡的简单实体(删除了一些真正无聊的列):
@Entity
@Cacheable(false)
@Table(name="PENDING_QUEUE"
, uniqueConstraints = @UniqueConstraint(columnNames="IEEXB_ID,QUEUE_TIMESTAMP")
)
public class PendingQueue implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name="ieexbId", column=@Column(name="IEEXB_ID", nullable=false) ),
@AttributeOverride(name="queueTimestamp", column=@Column(name="QUEUE_TIMESTAMP", nullable=false) ) } )
private PendingQueueId id;
@Column(name="IE_USER", nullable=false, length=21)
private String ieUser;
@Column(name="COMMAND_TYPE", nullable=false, length=3)
private String commandType;
public PendingQueue() {
;
}
public PendingQueue(PendingQueueId id, String ieUser, String commandType) {
super();
this.id = id;
this.ieUser = ieUser;
this.commandType = commandType;
}
public PendingQueueId getId() {
return id;
}
public void setId(PendingQueueId id) {
this.id = id;
}
public String getIeUser() {
return ieUser;
}
public void setIeUser(String ieUser) {
this.ieUser = ieUser;
}
public String getCommandType() {
return commandType;
}
public void setCommandType(String commandType) {
this.commandType = commandType;
}
....
}
当然是存储库:
@Repository
public interface PendingQueueRepository extends CrudRepository<PendingQueue, PendingQueueId> {
List<PendingQueue> findByIeUser(String ieUser);
}
最后是JUnit:
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles(profiles = {"data"})
@ContextConfiguration(classes = IeexbDataContextConfig.class, loader = AnnotationConfigContextLoader.class)
public class TestPendingQueue {
@Autowired
PendingQueueRepository pendingQueueRepository;
@Test
public void testFindByIeUser() {
List<PendingQueue> results = pendingQueueRepository.findByIeUser("JPA.XXX.BOB1");
System.out.println("Found Items:" + results.size());
System.out.println("First item is:" + results.get(0));
}
}
我正在尝试使用此VM ARG运行JUnit: -javaagent:C:\ Users \ Terry \ .m2 \ repository \ org \ springframework \ spring-agent \ 2.5.6.SEC03 \ spring-agent-2.5.6.SEC03.jar
我也尝试过添加AspectJ weaver,但它没有帮助 -javaagent:C:\用户\特里\的.m2 \库\有机\ AspectJ的\ aspectjweaver \ 1.8.0 \ aspectjweaver-1.8.0.jar
我没有尝试过Spring Tomcat织布工,但这似乎不是正确的方向。我读过人们然后遇到了JUnit找到类文件的问题。
没有粘贴在相当庞大的堆栈跟踪中,所有这一切归结为:
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.instrument.classloading.LoadTimeWeaver
com.xxx.ieexb.config.IeexbDataContextConfig.loadTimeWeaver()] threw exception; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method.
这当然是真的。该类加载器不支持编织。但我非常努力地不使用那个装载机。任何帮助表示赞赏
答案 0 :(得分:0)
我有类似的设置,并为我添加以下用于单元测试的VM args:
-javaagent:/path/to/spring-instrument-4.0.0.RELEASE.jar -javaagent:/path/to/aspectjweaver-1.8.0.jar
答案 1 :(得分:0)
看来问题是在@Configuration类中我包含了一个LoadTimeWeaver bean的定义。我还在EntityManagerFactory构造函数中设置了该值。通过删除,我不再在spring容器启动期间收到运行时错误。
查看Spring控制台,它说我的实体Bean被转换(编织)所以也许懒惰加载仍然可以工作 - 我没有任何数据库关联在这个特定的项目中尝试它。
另一个注意事项是, persistence.xml不是必需的不允许这样做。 Eclipselink正在寻找另一个我不知道的persistence.xml副本,这导致实体支持我的存储库不被发现。
但是现在我相信我发布的示例(减去loadTimeWeaving bean)显然是最好的,或者至少是最完整的示例之一 - 谁曾期望过!
答案 2 :(得分:0)
我无法完成上述工作。亚马逊aws不允许我把仪器jar放在tomcat / lib文件夹中,所以我不能使用-javaagent方法(相信我,我试过!)。我不得不切换到eclipselink static weaving
它不太难,需要一个persistence.xml文件,但是如果你已经使用了带注释的配置,它可以简短:
<?xml version="1.0" encoding="UTF-8"?>
<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="ADD_NAME_HERE">
<!--this is necessary for the eclipselink static weaving maven plugin-->
<!--this setting auto-detects entities in the project-->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
但请注意,它必须位于包含实体类的项目中。我犯了将pom.xml文件中的persistence.xml文件和maven插件放入我的网站项目而不是我的域项目的错误。
答案 3 :(得分:0)
如果需要通过maven设置-javaagent,它可以这样做:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/springframework/spring-instrument/${org.springframework.version}/spring-instrument-${org.springframework.version}.jar"
</argLine>
</configuration>
</plugin>
</plugins>
(只需设置$ {org.springframework.version}的属性或替换相应的版本) 这样它与您的项目相关联,而不是与您的jvm或webserver
相关联