1

リポジトリ サポートを 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 .jar

AspectJ ウィーバーも追加しようとしましたが、役に立ちませんでした -javaagent:C:\Users\Terry\.m2\repository\org\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.

これはもちろん真実です。そのクラスローダーはウィービングをサポートしていません。しかし、私はそのローダーを使用しないように非常に懸命に努力しました。どんな助けでも大歓迎

4

4 に答える 4

0

上記を機能させることができませんでした。Amazon 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>

ただし、エンティティ クラスを含むプロジェクト内になければならないことに注意してください。persistence.xml ファイルと pom.xml ファイル内の maven プラグインを、ドメイン プロジェクトではなく Web サイト プロジェクトにドロップするというミスを犯しました。

于 2016-11-04T15:54:26.017 に答える
0

同様の設定があり、単体テスト用に次の VM 引数を追加するとうまくいきます。

-javaagent:/path/to/spring-instrument-4.0.0.RELEASE.jar -javaagent:/path/to/aspectjweaver-1.8.0.jar
于 2014-05-01T16:30:17.977 に答える
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 や Web サーバーではなく、プロジェクトに関連付けられます

于 2017-08-28T09:01:27.150 に答える
0

問題は、 @Configuration クラスに LoadTimeWeaver Bean の定義を含めたことにあるようです。また、その値を EntityManagerFactory コンストラクター内に設定します。それを削除することで、Spring コンテナーの起動時にランタイム エラーが発生しなくなりました。

Spring コンソールを見ると、エンティティ Bean が変換された (織り込まれた) と表示されているため、おそらく遅延読み込みは引き続き機能します。この特定のプロジェクトで試してみるための DB 関連付けはありません。

もう1つの注意点は、persistence.xmlが必要ではないだけでなく、許可されていないことです。Eclipselink は、私が知らなかった persistence.xml の別のコピーを探していたため、リポジトリをサポートするエンティティが検出されませんでした。

しかし今のところ、私が投稿した例 (loadTimeWeaving Bean を除く) は、驚くべきことに、最高の、または少なくとも最も完全な例の 1 つであると信じています。

于 2014-05-02T16:59:22.220 に答える