mirror of
https://github.com/apache/openjpa.git
synced 2025-02-23 19:05:00 +00:00
OPENJPA-2220: Commit fetch statistic tool. Patch contributed by Helen Xu.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1356860 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dc339a98bc
commit
1de868af05
136
openjpa-tools/openjpa-fetch-statistics/pom.xml
Normal file
136
openjpa-tools/openjpa-fetch-statistics/pom.xml
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
you under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<!-- Maven release plugin requires the project tag to be on a single line. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa-tools</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>openjpa-fetch-statistics</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>OpenJPA Fetching Statistic Tool</name>
|
||||
<description>
|
||||
OpenJPA tool to capture the fetching statistic data for the persistent fields .
|
||||
</description>
|
||||
<inceptionYear>2012</inceptionYear>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jpa_2.0_spec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.1_spec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa-kernel</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa-lib</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa-persistence-jdbc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>${surefire.jvm.args}</argLine>
|
||||
<excludes>
|
||||
<!-- exclude the unit test since the fetch statistic enhancer cannot
|
||||
be load during maven build -->
|
||||
<exclude>org/apache/openjpa/enhance/stats/TestFetchStatistics.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>README-*.txt</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- Create another WAS specific jar -->
|
||||
<execution>
|
||||
<id>was</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<finalName>${artifactId}-${version}-websphere</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Fragment-Host>com.ibm.ws.jpa; bundle-version=8.0.0</Fragment-Host>
|
||||
<Export-Package>org.apache.openjpa.enhance.stats</Export-Package>
|
||||
<Bundle-SymbolicName>org.apache.openjpa.enhance.stats; singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-Name>FetchStatisticsAuxEnhancer</Bundle-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
<excludes>
|
||||
<exclude>README.txt</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
import org.apache.openjpa.enhance.PCEnhancer.AuxiliaryEnhancer;
|
||||
import org.apache.openjpa.lib.log.Log;
|
||||
import org.apache.openjpa.meta.AccessCode;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
|
||||
import serp.bytecode.BCClass;
|
||||
import serp.bytecode.BCMethod;
|
||||
import serp.bytecode.Code;
|
||||
|
||||
/**
|
||||
* FetchStatisticsAuxEnhancer adds the call back function to each persistent fields in the persistent entity which
|
||||
* will invoke the hit method from FetchStatsCollector whenever the field is fetched at runtime.
|
||||
*/
|
||||
public class FetchStatisticsAuxEnhancer implements AuxiliaryEnhancer {
|
||||
|
||||
private final String IGNORE_METHODS_REGEX = "(pc(.)*GenericContext)?(pc(.)*StateManager)?"
|
||||
+ "(pc(.)*DetachedState)?(pc(.)*EnhancementContractVersion)?(pc(.)*ManagedFieldCount)?(pc(.)*GetVersion)?";
|
||||
|
||||
public void run(BCClass bcc, ClassMetaData cmd) {
|
||||
addEnhancement(bcc, cmd);
|
||||
};
|
||||
|
||||
public boolean skipEnhance(BCMethod arg0) {
|
||||
return false;
|
||||
};
|
||||
|
||||
private void addEnhancement(BCClass bcc, ClassMetaData cmd) {
|
||||
Log log = cmd.getRepository().getConfiguration().getLog(OpenJPAConfiguration.LOG_RUNTIME);
|
||||
FetchStatsCollector.setlogger(log);
|
||||
for (BCMethod meth : bcc.getMethods()) {
|
||||
String methodName = meth.getName();
|
||||
FieldMetaData fmd = getFieldName(methodName, cmd);
|
||||
if (fmd != null && needsTracking(fmd, methodName, cmd)) {
|
||||
String fqn = bcc.getName() + "." + fmd.getName();
|
||||
FetchStatsCollector.registerField(fqn);
|
||||
FetchStatsCollector.registerEntity(cmd);
|
||||
|
||||
Code code = meth.getCode(false);
|
||||
code.constant().setValue(fqn);
|
||||
code.invokestatic().setMethod(FetchStatsCollector.class, "hit", void.class,
|
||||
new Class[] { String.class });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean needsTracking(FieldMetaData fmd, String methName, ClassMetaData cmd) {
|
||||
// Skim out primary key(s), versions, and LAZY fields
|
||||
if (fmd.isPrimaryKey() || fmd.isVersion() || !fmd.isInDefaultFetchGroup())
|
||||
return false;
|
||||
|
||||
if (AccessCode.isField(fmd) && methName.toLowerCase(Locale.ENGLISH).startsWith("pcget")) {
|
||||
return true;
|
||||
} else if (AccessCode.isProperty(fmd) && methName.toLowerCase(Locale.ENGLISH).startsWith("get")
|
||||
|| methName.toLowerCase(Locale.ENGLISH).startsWith("pcis")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private FieldMetaData getFieldName(String methName, ClassMetaData cmd) {
|
||||
FieldMetaData res = null;
|
||||
String fieldName = null;
|
||||
if (methName.matches(IGNORE_METHODS_REGEX)) {
|
||||
return res;
|
||||
} else if (methName.startsWith("pcGet")) {
|
||||
// field access
|
||||
fieldName = methName.substring(5);
|
||||
} else if (methName.toLowerCase(Locale.ENGLISH).startsWith("get")) {
|
||||
// property access
|
||||
fieldName = WordUtils.uncapitalize(methName.substring(3));
|
||||
} else if (methName.startsWith("pcis")) {
|
||||
fieldName = methName.substring(4).toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
for (FieldMetaData fmd : cmd.getDeclaredFields()) {
|
||||
String fmdName = fmd.getName();
|
||||
if (fmdName.equals(fieldName)) {
|
||||
return fmd;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.openjpa.lib.log.Log;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
* FetchStatsCollector aggregates fetch statistics and outputs the data periodically (10 minutes).
|
||||
*/
|
||||
public final class FetchStatsCollector {
|
||||
// Fully qualified persistent field name -> number of access
|
||||
private static ConcurrentHashMap<String, AtomicInteger> _used = new ConcurrentHashMap<String, AtomicInteger>();
|
||||
private static Set<String> _entities = new TreeSet<String>();
|
||||
|
||||
private static Log _log;
|
||||
private static final Localizer _loc = Localizer.forPackage(FetchStatsCollector.class);
|
||||
// default to 10 min
|
||||
private final static int DEFAULT_INTERVAL = 10 * 60 * 1000;
|
||||
private static Timer timer;
|
||||
|
||||
public static void setlogger(Log log) {
|
||||
if (FetchStatsCollector._log == null) {
|
||||
FetchStatsCollector._log = log;
|
||||
FetchStatsCollector._log.info(_loc.get("start-monitoring"));
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Shutdown());
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
TimerTask statsOutputTask = new TimerTask() {
|
||||
public void run() {
|
||||
dump();
|
||||
}
|
||||
};
|
||||
timer = new Timer();
|
||||
timer.schedule(statsOutputTask, DEFAULT_INTERVAL, DEFAULT_INTERVAL);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void registerEntity(ClassMetaData cmd) {
|
||||
_entities.add(cmd.getDescribedTypeString());
|
||||
}
|
||||
|
||||
public static AtomicInteger registerField(String field) {
|
||||
return _used.putIfAbsent(field, new AtomicInteger(Integer.valueOf(0)));
|
||||
}
|
||||
|
||||
public static void hit(String field) {
|
||||
AtomicInteger value = _used.get(field);
|
||||
if (value != null) {
|
||||
value.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
static class Shutdown extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
timer.cancel();
|
||||
dump();
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getStatistics() {
|
||||
// TreeSet for a sorted set.
|
||||
Set<String> noAccess = new TreeSet<String>();
|
||||
for (Map.Entry<String, AtomicInteger> entry : _used.entrySet()) {
|
||||
if (entry.getValue().intValue() == 0) {
|
||||
noAccess.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return noAccess;
|
||||
}
|
||||
|
||||
public static void dump() {
|
||||
Set<String> zeroAccessFieldSet = getStatistics();
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append(_loc.get("fields-never-fetched",
|
||||
new Object[] { _entities, new Integer(zeroAccessFieldSet.size()) }).getMessage());
|
||||
|
||||
for (String field : zeroAccessFieldSet) {
|
||||
message.append("\n\t" + field);
|
||||
|
||||
}
|
||||
_log.info(message);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
for (Map.Entry<String, AtomicInteger> entry : _used.entrySet()) {
|
||||
entry.setValue(new AtomicInteger(0));
|
||||
}
|
||||
}
|
||||
|
||||
static class Container {
|
||||
String _name;
|
||||
Integer _value;
|
||||
|
||||
public Container(String name, int value) {
|
||||
_name = name;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
org.apache.openjpa.enhance.stats.FetchStatisticsAuxEnhancer
|
@ -0,0 +1,29 @@
|
||||
Apache OpenJPA - README.txt
|
||||
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Open JPA Fetch Statistics Tool monitors persistent field access and determines which fields are never used. This tool
|
||||
can be used to help tune an application.
|
||||
|
||||
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
|
||||
|
||||
Usage instructions:
|
||||
|
||||
1.] Configuration
|
||||
* Add openjpa-fetch-statistics-[VERSION]-websphere.jar into the [WAS_HOME]\plugins directory.
|
||||
* Run [WAS_HOME]\bin\osgiCfgInit.sh(bat) to clear the osgi cache.
|
||||
|
||||
2.] Statistics Collecting and Monitoring
|
||||
* When this tool is configured, it will be active for all persistence units in the JVM. Statistics will be dumped via the
|
||||
openjpa.Runtime channel with the INFO level every 10 minutes, or when the JVM terminates. Any field that is logged
|
||||
has not been accessed by an application.
|
||||
|
||||
3.] Configuration removal
|
||||
* Stop all WebSphere processes using the [WAS_HOME]\plugins installation.
|
||||
* Remove the openjpa-fetch-statistics-[VERSION]-websphere.jar jar from the [WAS_HOME]\plugins directory.
|
||||
* Run [WAS_HOME]\bin\osgiCfgInit.sh(bat) to clear the osgi cache.
|
||||
|
||||
Performance Consideration
|
||||
|
||||
There will be a large performance impact when running this tooling. It is not supported, nor recommended for production
|
||||
use. This tool should not be used on a production machine.
|
@ -0,0 +1,64 @@
|
||||
Apache OpenJPA - README.txt
|
||||
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Open JPA Fetching Statistics Tool monitors the persistent fields
|
||||
fetching and finds out the fields which are never accessed. Based on the
|
||||
statistic data, user can set the field access type to LAZY to improve the
|
||||
performance by eliminating the data loading and processing time.
|
||||
|
||||
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
|
||||
|
||||
Usage instructions:
|
||||
|
||||
1 Classpath Configuration
|
||||
|
||||
Append the path of openjpa-fetch-statistics-version-SNAPSHOT.jar file
|
||||
to the classpath of the application before starting the application.
|
||||
|
||||
2 Statistics Collecting and Monitoring
|
||||
|
||||
Start the application with openjpa-fetch-statistics-<version>-SNAPSHOT.jar
|
||||
in the classpath. The tool will start collecting the statistics of the
|
||||
persistent field fetching and output the list of the persistent fields
|
||||
which have never been fetched to the log file every ten minutes.It will
|
||||
output the last list when the JVM is shutdown.
|
||||
|
||||
3 Termination
|
||||
Shut down the JVM to stop the fetching statistics collecting.
|
||||
Roll back the classpath configuration.
|
||||
Start the application without the fetching statistics jar in the classpath
|
||||
|
||||
Performance Consideration
|
||||
|
||||
There will be performance impact when the fetching statistics collection is on.
|
||||
The recommendation is to use it in the testing environment.
|
||||
|
||||
Apache OpenJPA - README.txt
|
||||
Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Open JPA Fetch Statistics Tool monitors persistent field access and determines which fields are never used. This tool
|
||||
can be used to help tune an application.
|
||||
|
||||
Note: Open JPA Fetching Statistics Tool works with the runtime enhancement.
|
||||
|
||||
Usage instructions:
|
||||
|
||||
1.] Configuration
|
||||
* Append the path of openjpa-fetch-statistics-version-SNAPSHOT.jar file to the classpath prior to lanuching the JVM.
|
||||
|
||||
2.] Statistics Collecting and Monitoring
|
||||
* When this tool is configured, it will be active for all persistence units in the JVM. Statistics will be dumped via the
|
||||
openjpa.Runtime channel with the INFO level every 10 minutes, or when the JVM terminates. Any field that is logged
|
||||
has not been accessed by an application.
|
||||
|
||||
3.] Configuration removal
|
||||
* Stop the JVM.
|
||||
* Remove openjpa-fetch-statistics-version-SNAPSHOT.jar from the classpath.
|
||||
|
||||
Performance Consideration
|
||||
|
||||
There will be a large performance impact when running this tooling. It is not supported, nor recommended for production
|
||||
use. This tool should not be used on a production machine.
|
||||
|
@ -0,0 +1,20 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
fields-never-fetched: Successfully collected fetch statistics from Entities {0}. The following fields are \
|
||||
FetchType.EAGER and were never fetched [ total {1} ] :
|
||||
start-monitoring: The FetchStatisticsAuxEnhancer has been loaded and is tracking persistent field usage.
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class AEntity {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
private String name;
|
||||
private String desc;
|
||||
private boolean checked;
|
||||
private EEntity extraInfo;
|
||||
|
||||
@ManyToOne
|
||||
private BEntity referredBEntity;
|
||||
|
||||
|
||||
public AEntity(int id, String name, String desc, BEntity bEntity) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
referredBEntity = bEntity;
|
||||
extraInfo = new EEntity("extra " + desc, "E" + id);
|
||||
}
|
||||
|
||||
public String getFullInfo(){
|
||||
return name + desc;
|
||||
}
|
||||
|
||||
|
||||
public boolean isChecked(){
|
||||
return checked;
|
||||
}
|
||||
|
||||
public String getReferredBEntityName(){
|
||||
return referredBEntity.getName();
|
||||
}
|
||||
|
||||
public String getExtraInfo(){
|
||||
return extraInfo.getExtraDesc();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
|
||||
@Entity
|
||||
@Inheritance(strategy=InheritanceType.JOINED)
|
||||
@Access(AccessType.PROPERTY)
|
||||
public class BEntity {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private boolean bool;
|
||||
|
||||
@Id
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Access(AccessType.FIELD)
|
||||
private String desc;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCustomDesc(){
|
||||
return desc;
|
||||
}
|
||||
|
||||
public BEntity(int id, String name, String desc) {
|
||||
super();
|
||||
setId(id);
|
||||
setName(name);
|
||||
setDesc(desc);
|
||||
}
|
||||
|
||||
public BEntity() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setBool(boolean b){
|
||||
bool = b;
|
||||
}
|
||||
|
||||
@Basic
|
||||
public boolean isBool(){
|
||||
return bool;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
|
||||
@Entity
|
||||
@PrimaryKeyJoinColumn(name = "CHILDID", referencedColumnName = "ID")
|
||||
public class ChildEntity extends BEntity {
|
||||
|
||||
private int childId;
|
||||
private String childName;
|
||||
private String childDesc;
|
||||
|
||||
public int getChildId() {
|
||||
return childId;
|
||||
}
|
||||
|
||||
public void setChildId(int childId) {
|
||||
this.childId = childId;
|
||||
}
|
||||
|
||||
public void setChildDesc(String childDesc) {
|
||||
this.childDesc = childDesc;
|
||||
}
|
||||
|
||||
public String getChildDesc() {
|
||||
return childDesc;
|
||||
}
|
||||
|
||||
public String getChildName() {
|
||||
return childName;
|
||||
}
|
||||
|
||||
public void setChildName(String childName) {
|
||||
this.childName = childName;
|
||||
}
|
||||
|
||||
public ChildEntity(int id, String name, String desc, String childName) {
|
||||
super(id, name, desc);
|
||||
setChildName(childName);
|
||||
setChildDesc("test");
|
||||
setChildId(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
|
||||
@Embeddable
|
||||
public class EEntity {
|
||||
String extraDesc;
|
||||
public String getExtraDesc() {
|
||||
return extraDesc;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
String code;
|
||||
|
||||
public EEntity (String desc, String code) {
|
||||
this.extraDesc = desc;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.openjpa.enhance.stats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
import org.apache.openjpa.enhance.PCEnhancer;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Unit test for Open JPA Fetch Statistic.
|
||||
*/
|
||||
public class TestFetchStatistics extends TestCase {
|
||||
|
||||
/**
|
||||
* Create the test case
|
||||
*
|
||||
* @param testName
|
||||
* name of the test case
|
||||
*/
|
||||
public TestFetchStatistics(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the suite of tests being tested
|
||||
*/
|
||||
public static Test suite() {
|
||||
return new TestSuite(TestFetchStatistics.class);
|
||||
}
|
||||
|
||||
public void setUp() {
|
||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("fetchStatisticPU");
|
||||
emf.createEntityManager().close();
|
||||
FetchStatsCollector.clear();
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
public void testFieldAccess() {
|
||||
FetchStatsCollector.clear();
|
||||
|
||||
AEntity aEntity = new AEntity(1, "t", "d", null);
|
||||
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.AEntity.name"));
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.AEntity.desc"));
|
||||
|
||||
assertEquals("td", aEntity.getFullInfo());
|
||||
res = FetchStatsCollector.getStatistics();
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.name"));
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.desc"));
|
||||
|
||||
}
|
||||
|
||||
public void testEmbeddedEntityFieldAccess() {
|
||||
AEntity aEntity = new AEntity(1, "t1", "d1", null);
|
||||
|
||||
assertEquals("extra d1", aEntity.getExtraInfo());
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.extraInfo"));
|
||||
}
|
||||
|
||||
public void testPropertyFieldMixedAccess() {
|
||||
FetchStatsCollector.clear();
|
||||
|
||||
BEntity b = new BEntity(2, "t2", "d2");
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertTrue(res.toString(), res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertTrue(res.toString(), res.contains("org.apache.openjpa.enhance.stats.BEntity.bool"));
|
||||
|
||||
b.getName();
|
||||
b.isBool();
|
||||
|
||||
res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.bool"));
|
||||
|
||||
}
|
||||
|
||||
public void testMixedAccess() {
|
||||
BEntity e = new BEntity(1, "t1", "d1");
|
||||
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
|
||||
|
||||
e.getName();
|
||||
e.getCustomDesc();
|
||||
|
||||
res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
|
||||
|
||||
}
|
||||
|
||||
public void testFieldAccessThroughRelationship() {
|
||||
BEntity bf1 = new BEntity(1, "t1", "d1");
|
||||
AEntity af3 = new AEntity(3, "t3", "d3", bf1);
|
||||
|
||||
assertEquals("t1", af3.getReferredBEntityName());
|
||||
af3.isChecked();
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.AEntity.checked"));
|
||||
}
|
||||
|
||||
public void testPropertyAccessThroughInheritance() {
|
||||
FetchStatsCollector.clear();
|
||||
|
||||
ChildEntity cEntity = new ChildEntity(1, "t1", "d1", "cn1");
|
||||
|
||||
Set<String> res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.ChildEntity.childName"));
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertTrue(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
|
||||
|
||||
// touch fields
|
||||
cEntity.getChildName();
|
||||
cEntity.getName();
|
||||
cEntity.getCustomDesc();
|
||||
|
||||
|
||||
res = FetchStatsCollector.getStatistics();
|
||||
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.ChildEntity.childName"));
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.name"));
|
||||
assertFalse(res.contains("org.apache.openjpa.enhance.stats.BEntity.desc"));
|
||||
}
|
||||
|
||||
// used for manual test of the output interval
|
||||
public void _testOutputInterval() throws InterruptedException {
|
||||
Thread.currentThread().sleep(60 * 60 * 1000);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership. The ASF licenses this file to
|
||||
you under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
|
||||
by applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing permissions and limitations under the License. -->
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
|
||||
|
||||
<persistence-unit name="fetchStatisticPU" transaction-type="RESOURCE_LOCAL">
|
||||
<description>PU for openjpa fetch statistic testing</description>
|
||||
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl
|
||||
</provider>
|
||||
<class>org.apache.openjpa.enhance.stats.AEntity</class>
|
||||
<class>org.apache.openjpa.enhance.stats.BEntity</class>
|
||||
<class>org.apache.openjpa.enhance.stats.ChildEntity</class>
|
||||
<class>org.apache.openjpa.enhance.stats.EEntity</class>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
@ -42,6 +42,8 @@
|
||||
|
||||
<modules>
|
||||
<module>openjpa-maven-plugin</module>
|
||||
<module>openjpa-fetch-statistics</module>
|
||||
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
|
Loading…
x
Reference in New Issue
Block a user