我正在尝试将存储库支持添加到 Eclipselink JPA Spring 项目。Eclipselink 需要 LoadTimeWeaving——尽管这不是绝对正确的,但我稍后希望 Aspects 也能正常工作。
生产应用程序在 Tomcat 下运行,如果我继续进行而不尝试创建 JUnit,我现在可能已经完成了。我有一种感觉,也许我真正拥有的是 Eciplse (STS 3.4) 问题,因为它似乎忽略了我的备用类加载器。但这似乎很基本,必须起作用,而且我做错了什么。
我只使用注释和 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 。罐
我也尝试添加 AspectJ weaver,但没有帮助 -javaagent:C:\Users\Terry\.m2\repository\org\aspectj\aspectjweaver\1.8.0\aspectjweaver-1.8.0.jar
我没有尝试过 Spring Tomcat weaver,但这似乎不是正确的方向。我读过人们在 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.
这当然是真的。该类加载器不支持编织。但是我已经非常非常努力地不使用该加载程序。任何帮助表示赞赏