The project uses the JPA partition approach to the library, and does not use Ali's set of Read and write separation (too cumbersome, too cumbersome ...). At the moment, the best provider should be hibernate, but unfortunately this feature is officially supported by the 5.0 version, which happens to Eclipselink 2.5.0, so we chose Eclipse link.
The hashpartition is also simple, that is, the data related to the sub-database field of the query, persisted operations point to the connection pool of the development database. It is relatively simple to apply.
@HashPartitioning (name= "Hashpartitionbysubid", [email protected] (name= "SubId"), connectionpools={"Default", "Node1 "})
@Partitioned ("Hashpartitionbysubid")
public class subentity{
}
It is possible to index with a positive value, 2.5.0 does not notice that it is possible to have a negative value when making a hash, and thus cause arrrayindexboundexception errors. Paste the code at a glance:
Org.eclipse.persistence.core-2.5.0.jar in Bag In Org.eclipse.persistence.descriptors.partitioning.HashPartitioningPolicy:
/**
* INTERNAL:
* Get a connection from one of the pools in a round robin rotation fashion.
*/
Public list<accessor> Getconnectionsforquery (abstractsession session, Databasequery query, Abstractrecord Arguments) {
Object value = Arguments.get (This.partitionfield);
if (value = = null) {
if (this.unionunpartitionablequeries) {
Use all connections.
list<accessor> accessors = new Arraylist<accessor> (This.connectionPools.size ());
for (String PoolName:this.connectionPools) {
Accessors.add (Getaccessor (poolname, session, query, false));
}
return accessors;
} else {
Use default behavior.
return null;
}
}
int index = Value.hashcode ()% this.connectionPools.size ();
if (Session.getplatform (). Haspartitioningcallback ()) {
UCP support.
Session.getplatform (). Getpartitioningcallback (). Setpartitionid (index);
return null;
}
Use the mapped connection pool.
list<accessor> accessors = new arraylist<accessor> (1);
String poolname = this.connectionPools.get (index);
Accessors.add (Getaccessor (poolname, session, query, false));
return accessors;
}
The problem is Varlue.hashcode (), the content may be negative, after the MoD calculation, the index becomes a negative value, directly resulting in Connectionpools.get (index) out of bounds.
Now, fortunately, the bug has been modified by 2.5.2.
/**
* INTERNAL:
* Get a connection from one of the pools in a round robin rotation fashion.
*/
Public list<accessor> Getconnectionsforquery (abstractsession session, Databasequery query, Abstractrecord Arguments) {
Object value = Arguments.get (This.partitionfield);
if (value = = null) {
if (this.unionunpartitionablequeries) {
Use all connections.
list<accessor> accessors = new Arraylist<accessor> (This.connectionPools.size ());
for (String PoolName:this.connectionPools) {
Accessors.add (Getaccessor (poolname, session, query, false));
}
return accessors;
} else {
Use default behavior.
return null;
}
}
int index = Math.Abs (Value.hashcode ())% this.connectionPools.size ();
if (Session.getplatform (). Haspartitioningcallback ()) {
UCP support.
Session.getplatform (). Getpartitioningcallback (). Setpartitionid (index);
return null;
}
Use the mapped connection pool.
list<accessor> accessors = new arraylist<accessor> (1);
String poolname = this.connectionPools.get (index);
Accessors.add (Getaccessor (poolname, session, query, false));
return accessors;
}
So if you use a JPA partition feature friend, it's best to upgrade the version to 2.5.2.
About Eclipselink 2.5.0 Hashpartition minor bug concerns