Unable to use multiple ebean databases in Play 2 - java

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()"

Related

How can I map a PostgreSQL varchar[] (array column) to a List<String> in Java using Hibernate?

I have a column in PostgreSQL 9.6 of type "character varying[]" which is essentially an array of strings. I am using Dropwizard with Hibernate to handle the database connection. Normally I just need to provide an annotation to define the data type, however, Hibernate is complaining about the deserialization of a varchar[] type. How do I map this to a List in Java?
I have tried implement my own UserType extended class to handle the (de)serialization with no luck. Any help would be most appreciated.
UPDATE:
I took a look at this link posted by #Waqas and I was able to at least create a type that extends UserType to implement the mapping of varchar[] to String[] in Java.
Some differences in my implementation:
In the nullSafeSet() and nullSafeGet() methods that need to be implemented (#Override), I had to use a (newer?) class called SharedSessionContractImplementor from org.hibernate.engine.spi instead of the (older?) class SessionImplementor.
When I implemented this change and added the #Type annotation to my column mapping (in my entity data class) my runtime was complaining about an #Override that apparently wasn't valid for a certain HibernateBundle class (error below). Even though maven built the jar without any issues and I only have Java 1.8 installed on my machine (OpenSuse). P.S. I am using Dropwizard 1.2 and I took the declaration of the HibernateBundle straight from their documentation. Nevertheless, I deleted the #Override annotation and it works now. Not sure why, or how, but it does.
Error as promised:
INFO [2017-11-08 22:39:06,220] org.eclipse.jetty.util.log: Logging initialized #1137ms to org.eclipse.jetty.util.log.Slf4jLog
INFO [2017-11-08 22:39:06,310] io.dropwizard.server.DefaultServerFactory: Registering jersey handler with root path prefix: /
INFO [2017-11-08 22:39:06,312] io.dropwizard.server.DefaultServerFactory: Registering admin handler with root path prefix: /
java.lang.Error: Unresolved compilation problem:
The method getDataSourceFactory(ApplicationConfiguration) of type new HibernateBundle<ApplicationConfiguration>(){} must override a superclass method
at com.tksoft.food.Application$1.getDataSourceFactory(Application.java:24)
at com.tksoft.food.Application$1.getDataSourceFactory(Application.java:1)
at io.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:61)
at io.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:15)
at io.dropwizard.setup.Bootstrap.run(Bootstrap.java:200)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:85)
at io.dropwizard.cli.Cli.run(Cli.java:75)
at io.dropwizard.Application.run(Application.java:93)
at com.tksoft.food.Application.main(Application.java:30)
Any way, this has left me super confused, but it is working so I am happy :) (for now). I just have to figure out if I can map it to a List instead of an array :/

How to create a simple plugin in Neo4j?

I configured Maven and managed to run example-Plugins like FullTextIndex (https://github.com/neo4j-contrib/neo4j-rdf/blob/master/src/main/java/org/neo4j/rdf/fulltext/FulltextIndex.java).
Still I struggle to create a simple Function by myself. I want to have a java-function that can find a node by ID and return its properties.
I know I can do this in Cypher, but the target is to understand the logic of plugins for Neo4j.
So after importing the plugin i should be able to type in:
INPUT ID
call example.function(217)
OUTPUT e. g.
name = Tree, age = 85, label = Plant, location = Munich
Thanks a lot!
In Neo4j, user-defined procedures are simple .jar files that you will put in the $NEO4J_HOME/plugins directory. Logically, to create a new user-defined procedure you will need to generate this jar file. You can do it configuring a new maven project or using the repository Neo4j Procedure Template.
User-defined procedures are simply Java classes with methods annotated with #Procedure. If the procedure writes in the database then mode = WRITE should be defined (not your case).
Also you will need query the database to get the node by ID and return the properties. To do it you will need inject in your Java class the GraphDatabaseService class using the #Context annotation.
To achieve your goal, I believe that you will need to use the getNodeById() method from GraphDatabaseService and the getProperties() in the returned Node.
What you are looking for is User Defined Functions / Procedures. There is a dedicated section in the neo4j documentation :
https://neo4j.com/developer/procedures-functions/#_extending_cypher
http://neo4j.com/docs/developer-manual/current/extending-neo4j/procedures/#user-defined-procedures
You can also look at APOC which contains hundreds of such examples used in real life.
https://github.com/neo4j-contrib/neo4j-apoc-procedures

Description on JMX fields and methods JBoss

How can we add description on the fields and operations exposed for JMX?
JBoss version : JBoss EAP 5.1.2
We have a Service bean as
#Service
#Management(MyConfigMgnt.class)
public class MyConfigService implements MyConfigLocal, MyConfigMgnt {
public void setMyValue(String MyValue){}
public String getMyValue(){}
}
These methods are declared in the MyConfigMgnt interface.
This is visible in the jboss jmx console as
and for the field it is shown as
How do we add relevant and proper information on the fields and the MBean.
Thanks
There's 2 ways of doing this.
Re-implement your service as a DynamicMBean which is slightly more complicated but allows for the definition of attribute and operation meta-data. (i.e. MyConfigMgnt extends DynamicMBean)
An easier way (but possibly not future-proof) is to use an XMBean descriptor. XMBeans are a proprietary JBoss JMX extension where meta-data is defined in an external XML resource. It would require no actual changes to the source code except the addition of the XMBean resource location which looks something like this:
#Service(objectName = XMBeanService.OBJECT_NAME, xmbean = "resource:META-INF/service-xmbean.xml")
If you have a very large number of attributes and operations, the XMBean XML descriptor can be arduous to write, but twiddle has a helper command which will generate a template specific to your existing simple MBean, so you can save the output, fill in the details and go from there.

Objectify Transactions using VoidWork

I am using Objectify version 4. I want to use transactions in my project. Project is based on GWT Java and objectify. As per objectify tutorials i found that ofy().transact() method to be used. So i preferred to use the following
ofy().transact(new VoidWork() {
public void vrun() {
Here i wrote code for saving data to entity
}
});
When i execute the project on development server/local i get a error message stating that
No source code is available for type com.googlecode.objectify.VoidWork; did you forget to inherit a required module?
The method createBillingDocs() is undefined for the type new VoidWork(){}
createBillingDocs is my method which i want to execute in transaction.
So any help?
Thanks in advance
You can't run transactions or use Objectify client-side; it is a server-side framework for accessing the datastore. You need to separate out your client-side logic from your server-side logic and define your GWT modules carefully.

Java Hibernate field access property or property based access

i am developing some improvements over a legacy system have some quite time
i have a class like this
class MyPersistentClazz
{
private String aTPlace;
public void setATPlace(.......){......}//yes mistyping
#Column(name="atPlaceOrder")
public String getATPlace(){return aTPlace;}
}
they usually load this class using this methods
final MyPersistentClazz clazz = (MyPersistentClazz)session.createCriteria(MyPersistentClazz.class).add(idEq(id)).uniqueResult();
and using load and get methods and works OK.
but the problem arise when i use projections.
final Projection p=Projections.projectionList().add(Projections.property("d.aTPlace"),"aTPlace");
throws
Exception in thread "main" org.hibernate.QueryException: could not resolve property:
my question is...
when using projections i think Hibernate is calling the setter of each property is this assertion OK?
when using criteria.uniqueResult or load or get Hibernate use individual field property access?
or why works with some and not work with others with the same setter?
we are using only annotations not XML.
thanks a lot.
How Hibernate works with your bean depends on how you annotated it. If you annotate instance variables then Hibernate will use direct injection and bypass your Set methods. Otherwise, it will use your Set methods.
Could it be that it is incorrectly converting your property name to a Set method name? Try changing the property name to something simpler (without that series of capital letters), and ensure that the case of the property in your projection is correct.

Categories