I am trying to persist my stateful session and trying to use the example from the JBoss documentation:
// create the entity manager factory and register it in the environment
EntityManagerFactory emf =
Persistence.createEntityManagerFactory( "org.jbpm.persistence.jpa" );
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
// create a new KIE session that uses JPA to store the runtime state
StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
int sessionId = ksession.getId();
The class KnowledgeBaseFactory does not have a newEnvironment() method. I have searched and tried different versions and imports to no avail. I currently have 7.20.0.Final but I have tried several others.
The code snipped I posted above is from: https://docs.jboss.org/jbpm/release/7.20.0.Final/jbpm-docs/html_single/#_manually_configuring_the_jbpm_engine_to_use_persistence.
I am not sure what I am missing or what the correct import is.
UPDATE:
So after some more research it looks like they keep putting this in their documentation though they have deprecated and the method I couldn't find doesn't exist and you have to go back to a 6.x.x release to find it. Why it's still in their documentation as an example when it doesn't exist is beyond me and wasted a lot of my time.
Related
I have integrated open-telemetry collector with spring-cloud-sleuth.
I have created a spring aspect where I am trying to add a custom baggage field serviceName to the current trace using following line of code (Reference)
tracer.createBaggage( "serviceName", "spring-cloud-sleuth-otel-slf4j" );
This works but the baggage is added from the next span onwards. I found the following solution (here) which is supposed to solve this but it works with brave only
#Bean
ScopeDecorator mdcScopeDecorator() {
return MDCScopeDecorator.newBuilder().clear().add( SingleCorrelationField.newBuilder( countryCodeField() ).flushOnUpdate().build() ).build();
}
However, I could not find anything similar when not using brave. Can somebody suggest how it can be achieved?
I recently upgraded/migrated my Spring Batch Java application from spring-boot-starter-parent-1.5.9.RELEASE to -> spring-boot-starter-parent-2.2.4.RELEASE, which subsequently pulls in the 5.X.X (5.2.3.RELEASE to be exact) springframework dependencies (before I was using 4.X.X). Some of the main ones I'm using are:
spring-boot-starter-parent-2.2.4
spring-boot-starter-batch
spring-boot-starter-jpa
spring-boot-starter-web
hibernate-core
hibernate-envers
hibernate-entitymanager
postgresql
For context, my application reads in .csv files and parses out the data and simply writes it to a postgresql database.
After many hours of debugging today, I know see that my first call to write data to the database, which is done by a JpaRepository method called saveAll(), which basically takes an ArrayList (Iterable) of Entities and batch inserts them to database, is failing somewhere when it enters the JdkDynamicAopProxyClass from the Spring AOP library. Previously, I was using the save() method, but this didn't work anymore once I upgraded my dependencies.
I know its failing here because I debugged meticulously and see that once it hits the saveAll() method in my java class that implements the ItemWriter<S> for Spring Batch, it enters the public Object invoke(Object proxy, Method method, Object[] args) method in the JdkDynamicAopProxyClass, and ends up throwing an exception, after doing a huge weird loop in the library code that's hard to follow.
I also debugged my old Application that WAS WORKING when it was running on spring-boot-starter-1.5.9 as I stated previously, and I see that when it gets to that public Object invoke() method (I mentioned above), it returns an ArrayList of the entities (which is correct) to write to the Database when it hits this line of code inside that method:
public Object invoke(Object proxy, Method method, Object[] args) {
// code here...
// this is where I notice a difference in return type from the "working" code vs. "broken
// code"
retVal = invocation.proceed();
// more code here...
Object var12 = retVal;
return var12;
HOWEVER, when I debugged my new migrated code (that was upgraded to spring 2.X.X/5.X.X, I see it returns a DefaultTransactionStatus#14037 object, which clearly is wrong. It then enters the protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary() method in the TransactionAspectSupport class from the spring-tx library. It will then have the retVal variable in the invoke method I mentioned above equal to null and it will start looping a few times more, over the same parts of code in a circle. It will have the txInfo set as PROPAGATION_REQUIRES_NEW,ISOLATION_SERIALIZABLE. I can click the "Step Into" button in IntelliJ and it will let me step through forever. Its like a infinite loop.
I'm not sure what to post, or if there are any clues here. I googled and found other people have similiar issues, and it seemed to revolve around (possibly) the transaction manager or entity manager and how the Beans were setup in the configuration class.
I tried everything I read, but nothing worked. I'm not an expert with Spring Batch or Spring so maybe I am missing something here.
I also noticed when I was debugging my working code, it had a variable Target = SimpleJpaRepository#11243 and it had some properties like a ArrayList of Providers
Em = Shared EntityManager proxy for target factory [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#6f2b608e]
Provider = HIBERNATE
org.hibernate.Session [0]
org.hibernate.jpa.HibernateEntityManager [1]
org.hibernate.ejb.HibernateEntityManager [2]
The odd thing was when I debugged my "broken" code, it seemed to only have the org.hibernate.jpa.HibernateEntityManager in its List in this variable
If anyone can please let me know if there are some clues pointing to something, I would immensely appreciate it. I really think its a Bean config, Entity Manager/Transaction-issue, but I'm not an expert so I'm not sure. I thought it was a dependency issue at first, but after being on google that changed my mind.
How do I add global variables to an embedded Gremlin server instance?
Also, I want to avoid loading the server configuration from a file, although I can load resources from the classpath.
getGlobalBindings() on GremlinExecutor is indeed deprecated, but the javadoc explains how you should proceed:
replaced by getScriptEngineManager() to add global scoped bindings
directly to that object.
That comes from the 3.2.5 javadoc when it was originally deprecated in preparation for pretty large changes in 3.3.0 when new interfaces were implement to better generalize the GremlinScriptEngine. While these new interfaces were defined for default use in 3.3.0, they are actually present in 3.2.x and may be used there. Note that the getGlobalBindings() method was actually removed completely in 3.3.0 so when you upgrade you will end up with compilation errors.
Where there may be some confusion with respect to that javadoc comment is that to use the getScriptEngineManager() you must also use what is the default 3.3.0 yaml configuration on the 3.2.x line of code...an example is shown here:
https://github.com/apache/tinkerpop/blob/3.3.0/gremlin-server/conf/gremlin-server-classic.yaml#L25
Note that under this new model, you have two other options for adding global bindings...you could also either:
Use the BindingsGremlinPlugin to add global bindings programmatically
Write your own GremlinPlugin instance to add your bindings
Looks like we can do it this way, although getGlobalBindings() is deprecated.
Graph graph = this.createGraph();
GraphTraversalSource g = graph.traversal();
this.server = new GremlinServer(getSettings());
this.server.getServerGremlinExecutor().getGraphManager().putGraph("graph", graph);
this.server.getServerGremlinExecutor().getGremlinExecutor().getGlobalBindings().put("graph", graph);
this.server.getServerGremlinExecutor().getGremlinExecutor().getGlobalBindings().put("g", g);
this.server.start();
I'm trying to implement a few tests with JBPM 6. I'm currently working a a simple hello world bpmn2 file, which is loaded correctly.
My understading of the documentation ( Click ) is that persistence should be disabled by default. "By default, if you do not configure the process engine otherwise, process instances are not made persistent."
However, when I try to implement it, and without doing anything special to enable persistence, I hit persistence related problems every time I try to do anything.
javax.persistence.PersistenceException: No Persistence provider for EntityManager named org.jbpm.persistence.jpa
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:69)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
at org.jbpm.runtime.manager.impl.jpa.EntityManagerFactoryManager.getOrCreate(EntityManagerFactoryManager.java:33)
at org.jbpm.runtime.manager.impl.DefaultRuntimeEnvironment.init(DefaultRuntimeEnvironment.java:73)
at org.jbpm.runtime.manager.impl.RuntimeEnvironmentBuilder.get(RuntimeEnvironmentBuilder.java:400)
at org.jbpm.runtime.manager.impl.RuntimeEnvironmentBuilder.get(RuntimeEnvironmentBuilder.java:74)</blockquote>
I Create my runtime environement the following way,
RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get()
.newDefaultInMemoryBuilder()
.persistence(false)
.addAsset(ResourceFactory.newClassPathResource("examples/helloworld.bpmn2.xml"), ResourceType.BPMN2)
.addAsset(ResourceFactory.newClassPathResource("examples/newBPMNProcess.bpmn"), ResourceType.BPMN2)
.get();
As my understanding is that persistence should be disabled by default, I don't see what I'm doing wrong. It could be linked to something included in some of my dependencies, but I don't have found anything on it either.
Has anybody faced the same issue already or has any advice.
Thanks
A RuntimeManager is a combination of a process engine and a human task service. The human task service needs persistence (to start the human tasks etc.), that's why it's still asking for a datasource, even if you configure the engine to not use persistence.
If you want to use an engine without our human task service, you don't need persistence at all, but I wouldn't use a RuntimeManager in that case, simply create a ksession from the kbase directly:
http://docs.jboss.org/jbpm/v6.1/userguide/jBPMCoreEngine.html#d0e1805
The InMemoryBuilder which you use in your code is supposed to (as per API documentation) not be persistent, but it is actually adding a persistence manager to the environment, just with an InMemoryMapper instead of a JPAMapper because of the way the init() method in DefaultRuntimeEnvironment is implemented:
public void init() {
if (emf == null && getEnvironmentTemplate().get(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER) == null) {
emf = EntityManagerFactoryManager.get().getOrCreate("org.jbpm.persistence.jpa");
}
addToEnvironment(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
if (this.mapper == null) {
if (this.usePersistence) {
this.mapper = new JPAMapper(emf);
} else {
this.mapper = new InMemoryMapper();
}
}
}
As you can see above, this still tries to getOrCreate() a persistence unit (I have seen a better implementation which also checks for the value of persistence attribute somewhere, but the issue here is, DefaultRuntimeEnvironment doesn't do that).
What you need to start with to get away without persistence is a newEmptyBuilder():
RuntimeEnvironment env = RuntimeEnvironmentBuilder.Factory.get()
.newEmptyBuilder()
.knowledgeBase(KieServices.Factory.get().getKieClasspathContainer().getKieBase("my-knowledge-base"))
// ONLY REQUIRED FOR PER-REQUEST AND PER-INSTANCE STRATEGY
//.addEnvironmentEntry("IS_JTA_TRANSACTION", false)
.persistence(false)
.get();
Do mind though that this will only work for Singleton runtime managers - PerProcessInstance and PerRequest expect to be able to suspend a running transaction if necessary, which is only possible if you have an entity manager to be able to persist state.
For testing with those two strategies also use addEnvironmentEntry() above.
We are setting up a slightly complicated project using Play Framework 2.0.3.
We need to access several databases (pre-existing) and would like to do it using the frameworks built-in facilities (ie. EBean).
We tried to create all model classes within the "models" package, and then map each class with its FQN to the corresponding EBean property in the application.conf:
ebean.firstDB="models.ClassA,models.ClassB,models.ClassC"
ebean.secondDB="models.ClassD"
ebean.thirdDB="models.ClassE,models.ClassF"
This doesn't seem to work:
PersistenceException: Error with [models.SomeClass] It has not been enhanced but it's superClass [class play.db.ebean.Model] is? (You are not allowed to mix enhancement in a single inheritance hierarchy) marker[play.db.ebean.Model] className[models.SomeClass]
We checked and re-checked and the configuration is OK!
We then tried to use a different Java package for each database model classes and map them accordingly in the application.conf:
ebean.firstDB = "packageA.*"
ebean.secondDB = "packageB.*"
ebean.thirdDB = "packageC.*"
This works fine when reading information from the database, but when you try to save/update objects we get:
PersistenceException: The default EbeanServer has not been defined? This is normally set via the ebean.datasource.default property. Otherwise it should be registered programatically via registerServer()
Any ideas?
Thanks!
Ricardo
You have to specify in your query which database you want to access.
For example, if you want to retrieve all users from your secondDB :
// Get access to your secondDB
EbeanServer secondDB = Ebean.getServer("secondDB");
// Get all users in secondDB
List<User> userList = secondDB.find(User.class).findList();
When using save(), delete(), update() or refresh(), you have to specify the Ebean server, for instance for the save() method:
classA.save("firstDB");
I have encounter the same problem and waste a whole day to investigate into it,finally I have got it.
1.define named eabean server
db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost:3306/db1"
db.default.user=root
db.default.password=123456
db.aux.driver=com.mysql.jdbc.Driver
db.aux.url="jdbc:mysql://localhost:3306/db2"
db.aux.user=root
db.aux.password=123456
now you have two ebean server [default] and [aux] at run time.
2.app conf file
ebean.default="models.*"
ebean.aux= "secondary.*"
Now entiies under package models.* configured to [default] server and entities under package secondary.* configured to [aux] server. I think this may related to java class enhancement or something. You don't need to separate Entities into different packages, but if entities of different ebean servers are under same package, it may cause weird trouble and exceptions.
When using you model, save/delete/update related method should add server name as parameter
Student s = new Student(); s.save("aux");
When use finder,you should define your finder as
public static Finder find = new Finder("aux",Long.class,Student.class);
Might not be the same case, I ran to this SomeClass not enhanced PersistenceException with Play 2.1.0,
and only what was missing was a public declaration in SomeClass model class that I had forgotten..
In Play 2.1.0 the error message was a little different:
PersistenceException: java.lang.IllegalStateException: Class [class play.db.ebean.Model] is enhanced and [class models.Address] is not - (you can not mix!!)
This solved my issue with saving to my db table and resolving the error:
"javax.persistence.PersistenceException: The default EbeanServer has not been defined ? This is normally set via the ebean.datasource.default property. Otherwise it should be registered programatically via registerServer()"