1

clojure.core provides bean that creates a clojure map from a java object but is there an inverse function that creates a bean (java object) from a map?

3
  • Do you mean to generate a new bean class from a map? Or to use the entries in a map to populate a bean of an existing bean class? Commented Oct 17, 2017 at 13:49
  • I was thinking to just return an Object. So {:foo "bar"} becomes o.foo == "bar" Commented Oct 17, 2017 at 13:53
  • 5
    That's not an Object because java.lang.Object has no fields. Commented Oct 17, 2017 at 14:26

2 Answers 2

3

Depends on what you need exactly.

Bean type exists in Java

In other words, you have (let's say) a Customer.class in your java project and you'd like to have that instantiated and filled in via Clojure based on the data in your map. This can be done simply via java interop.

Bean type created in Clojure

You can use AOT compilation to create a Javabean type, which will result in a .class file on the disk and can be used in a Java project (in the same way as any Java class, that does not have a corresponding Java source). You can use the clj-bean library to avoid using gen-class manually.

Bean type created in Clojure - dynamically, without .class file

In this case, you can use deftype to create the bean via dynamic bytecode creation (simply create methods for the getters and setters and move the data from-to the map).

You can find examples of all the above ways in this project

Sign up to request clarification or add additional context in comments.

Comments

2

There are various libraries that perform Clojure map <-> Java Bean translation, including one I authored called bean-dip. Here's the breakdown in the README on the other options considered and what distinguishes bean-dip:

...

Existing translation solutions had feature gaps that lead us to create bean-dip: The clojure.core/bean built-in is one-way, uses uncached reflection and can't be configured. Cached reflection is available via gavagai, but it's only one-way. There's java.data, which is bidirectional, recursive and reflection-free, but it's not declarative making large translation layers hard to maintain.

Bean-dip is:

  • Bidirectional: Translate from beans to maps and back again
  • Declarative: Just specify the bean class and a set of keys for corresponding maps
  • Recursive: Translation descends into nested beans when they also have translations defined
  • Reflection-free: Macro generates type hinted code that can be name checked at compile time via *warn-on-reflection*
  • Extensible: Translate values by key via implementations of multimethods

Namespaced keys are supported making it easy to enforce contracts with Java APIs using specs...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.