Language-Natural Persistence Layer for Java

Overview

Permazen is a better persistence layer for Java

Persistence is central to most applications. But there are many challenges involved in persistence programming that lie outside of the domain of simply storing the data.

Mainstream Java solutions such as JDBC, JPA and JDO were designed simply to give Java programmers access to existing database functionality. They address the "storage" problem, but leave many other important issues that are inherent to persistence programming poorly addressed, or not addressed at all.

Permazen is a completely different way of looking at persistence programming. Instead of starting from the storage technology side, it starts from the programming language side, asking the simple question, "What are the issues that are inherent to persistence programming, regardless of programming language or database storage technology, and how can they be addressed at the language level in the simplest, most correct, and most language-natural way?"

With Permazen, not only are many issues inherent to persistence programming solved more easily and naturally than before, but also many issues that traditional solutions don't address at all are solved, and some entirely new, useful functionality is added.

Permazen is:

  • A Java persistence layer for SQL, key-value, or in-memory databases
  • A rigorously defined, modular key/value API with adapters for multiple database technologies
  • A way to make your application portable across different database technologies
  • An object serialization framework
  • An automated schema management framework
  • A library for inverting Java references
  • A library for automatic field change notification
  • An embeddable Java command line interface (CLI)

Permazen was inspired by years of frustration with existing persistence solutions, in particular JPA. Compared to using JPA, building an application with Permazen is a refreshingly straightforward experience.

Ask these questions of your persistence solution:

  • Configuration complexity Do we have to explicitly configure details of how data is mapped? Are we forced to (ab)use the programming language to address what are really database configuration issues?
  • Query language concordance Does the code that performs queries look like regular Java code, or do we have to learn a new “query language”?
  • Query performance transparency Is the performance of a query visible and obvious from looking at the code that performs it?
  • Data type congruence Are database types equivalent to Java types across the entire domain of values? Are we guaranteed to always read back the same value we write?
  • First class offline data Can it be precisely defined which data is copied out of a transaction? Does offline data have all the rights and privileges of “online” (i.e., transactional) data? Does this include the ability to query indexes, and a framework for handling schema differences? Can offline data be easily serialized/deserialized?
  • Schema verification Is the schema assumed by the code cross-checked against the schema actually present in the database? Are we always guaranteed a consistent interpretation of stored data?
  • Incremental schema evolution Can multiple schemas exist at the same time in the database, to support rolling upgrades? Can data be migrated incrementally, i.e., without stopping the world? Are we free from "whole database" migration operations that would limit scalability?
  • Structural schema changes Are structural schema updates performed entirely automatically for us?
  • Semantic schema changes Is there a convenient way to specify semantic schema updates, at the language level (not the database level)?
  • Schema evolution type safety Is type safety and data type congruence guaranteed across arbitrary schema migrations?
  • Transactional validation Does validation, including reference validation, occur only at the end of the transaction (as it should), or randomly and inconveniently in the middle?
  • Cross-object validation Is it possible to define validation constraints that span multiple objects/records? Can we register for data-level notifications about changes in non-local objects?
  • Custom types and indexes Is it possible to define custom data types, have them be indexed? Is it easy to define arbitrary custom indexes?
  • Language-level data maintainability Can database maintenance tasks and queries be performed via a command line interface (CLI) using Java types, values, and expressions (including Java 8 streams and lambdas)? Are there convenient tools for manual and scripted use?
  • Data store independence Are we restricted to using only a specific type of database technology, or can virtually any database technology be used by implementing a simple API, making it easy to change later if needed?

Permazen addresses all of these issues, this without sacrificing flexibility or scalability.

Permazen does this by treating the database as just a sorted key/value store, and implementing the following in Java:

  • Encoding/decoding of field values
  • Referential integrity; forward/reverse delete cascades
  • Indexes (simple and composite)
  • Query views
  • Schema management
  • Change notification
  • Validation queues
  • Command line interface
  • GUI database editor

Permazen also adds several new features that traditional databases don't provide.

What's the Downside?

Permazen gains advantages by fundamentally changing the equation with respect to persistence programming. However, in some situations, not all of these changes result in improvements when compared to traditional SQL/JPA. Here are some things to consider.

You have to learn something new. Persistence programming with Permazen requires a different way of thinking. For example, a "DAO" layer is often no longer necessary, and you have to think harder about how to query your data efficiently (instead of crossing your fingers and hoping the database figures it out for you).

For an equivalent query, Permazen will perform more frequent, but smaller, database accesses. As a result, in situations where the code and the data are separated by a high latency network, Permazen will tend to be slower.

More flexible type hiearchies are possible, but it's also easy to make a mess. JPA has support for class inheritance and partial support for generics. Permazen supports interface inheritance (including Java's equivalent of "mix-ins") and fully supports generic types. The restrictions imposed by JPA tend to force model classes to stay simpler. With Permazen, implementing an interface (directly or indirectly) can mean that a model class inherits a bunch of new persistent fields.

Permazen Slides

For a quick overview, check out these slides from a JSimpleDB talk at a local Java user's group (Permazen was previously named JSimpleDB).

Permazen Paper

For a deeper understanding of the motivation and design decisions behind Permazen, read Permazen: Language-Driven Persistence for Java.

Abstract:

Most software applications require durable persistence of data. From a programmer’s point of view, persistence has its own set of inherent issues, e.g., how to manage schema changes, yet such issues are rarely addressed in the programming language itself. Instead, how we program for persistence has traditionally been driven by the storage technology side, resulting in incomplete and/or technology-specific support for managing those issues.

In Java, the mainstream solution for basic persistence is the Java Persistence API (JPA). While popular, it also measures poorly on how well it addresses many of these inherent issues. We identify several examples, and generalize them into criteria for evaluating how well any solution serves the programmer’s persistence needs, in any language. We introduce Permazen, a persistence layer for ordered key/value stores that, by integrating the data encoding, query, and indexing functions, provides a more complete, type-safe, and language-driven framework for managing persistence in Java, and addresses all of the issues we identify.

Installing Permazen

Permazen is available from Maven Central:

    <dependency>
        <groupId>io.permazen</groupId>
        <artifactId>permazen-main</artifactId>
    </dependency>

or from the Ivy RoundUp ivy repository:

<dependency org="io.permazen" name="permazen"/>

You should also add the key/value store module(s) for whatever key/value store(s) you want to use, e.g.:

    <dependency>
        <groupId>io.permazen</groupId>
        <artifactId>permazen-kv-sqlite</artifactId>
    </dependency>

There is a demo distribution ZIP file that lets you play with the Permazen command line and GUI, using a simple database of the solar system.

Documentation

Documentation and links:

Comments
  • Why not non-final classes?

    Why not non-final classes?

    In the introduction, "The model class can be an abstract class or an interface" is stated.

    Why not support POJOs that are not final and that do not have any final methods?

    Incidentally, a later bullet: "This makes life easier, but there is no requirement that the model class extend or implement anything" should be indented.

    opened by paul-hammant 12
  • How to get started with BDB

    How to get started with BDB

    BerkeleyKVDatabase kvdb = new BerkeleyKVDatabase();
    kvdb.setDirectory(new File("."));
    kvdb.setDatabaseName("fred");
    kvdb.start();
    jdb = new JSimpleDBFactory()
        .setDatabase(new Database(kvdb))
        .setSchemaVersion(-1)
        .setModelClasses(Person.class).newJSimpleDB();
    final JTransaction txn = jdb.createTransaction(true, ValidationMode.AUTOMATIC);
    JTransaction.setCurrent(txn);
    

    The above gives:

    org.jsimpledb.kv.RetryTransactionException: transaction must be retried
    
    	at org.jsimpledb.kv.bdb.BerkeleyKVTransaction.wrapException(BerkeleyKVTransaction.java:265)
    	at org.jsimpledb.kv.bdb.BerkeleyKVTransaction$CursorIterator.findNext(BerkeleyKVTransaction.java:395)
    	at org.jsimpledb.kv.bdb.BerkeleyKVTransaction$CursorIterator.hasNext(BerkeleyKVTransaction.java:312)
    	at org.jsimpledb.core.Database.verifySchemas(Database.java:471)
    	at org.jsimpledb.core.Database.createTransaction(Database.java:304)
    	at org.jsimpledb.core.Database.createTransaction(Database.java:254)
    	at org.jsimpledb.JSimpleDB.createTransaction(JSimpleDB.java:581)
    	at org.jsimpledb.JSimpleDB.createTransaction(JSimpleDB.java:551)
    	at de.protubero.ajs.PersonStoreImpl.selectById(PersonStoreImpl.java:80)
    	at de.protubero.ajs.PersonStoreTest.shouldBeAbleToDeleteKnownPerson(PersonStoreTest.java:33)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    Caused by: com.sleepycat.je.LockTimeoutException: (JE 6.4.9) Lock expired. Locker 1328238652 11_main_Txn: waited for lock on database=fred LockAddr:785570251 LSN=0x0/0x1265 type=RANGE_READ grant=WAIT_NEW timeoutMillis=500 startTime=1502933461314 endTime=1502933461816
    Owners: [<LockInfo locker="1926096844 10_main_Txn" type="RANGE_WRITE"/>]
    Waiters: []
    
    	at com.sleepycat.je.txn.LockManager.newLockTimeoutException(LockManager.java:736)
    	at com.sleepycat.je.txn.LockManager.makeTimeoutException(LockManager.java:590)
    	at com.sleepycat.je.txn.LockManager.lockInternal(LockManager.java:417)
    	at com.sleepycat.je.txn.LockManager.lock(LockManager.java:295)
    	at com.sleepycat.je.txn.Txn.lockInternal(Txn.java:567)
    	at com.sleepycat.je.txn.Locker.lock(Locker.java:504)
    	at com.sleepycat.je.dbi.CursorImpl.lockLN(CursorImpl.java:3551)
    	at com.sleepycat.je.dbi.CursorImpl.lockLN(CursorImpl.java:3346)
    	at com.sleepycat.je.dbi.CursorImpl.lockLNAndCheckDeleted(CursorImpl.java:2149)
    	at com.sleepycat.je.dbi.CursorImpl.lockAndGetCurrent(CursorImpl.java:2074)
    	at com.sleepycat.je.dbi.CursorImpl.getNext(CursorImpl.java:2552)
    	at com.sleepycat.je.Cursor.retrieveNextCheckForInsertion(Cursor.java:3212)
    	at com.sleepycat.je.Cursor.retrieveNextNoDups(Cursor.java:3094)
    	at com.sleepycat.je.Cursor.retrieveNext(Cursor.java:2836)
    	at com.sleepycat.je.Cursor.getNext(Cursor.java:1117)
    	at org.jsimpledb.kv.bdb.BerkeleyKVTransaction$CursorIterator.findNext(BerkeleyKVTransaction.java:379)
    	... 30 more
    

    If I comment out the start() operation:

    java.lang.IllegalStateException: not started
    
    	at com.google.common.base.Preconditions.checkState(Preconditions.java:444)
    	at org.jsimpledb.kv.bdb.BerkeleyKVDatabase.createTransaction(BerkeleyKVDatabase.java:274)
    	at org.jsimpledb.kv.bdb.BerkeleyKVDatabase.createTransaction(BerkeleyKVDatabase.java:267)
    	at org.jsimpledb.kv.bdb.BerkeleyKVDatabase.createTransaction(BerkeleyKVDatabase.java:41)
    	at org.jsimpledb.core.Database.createTransaction(Database.java:251)
    	at org.jsimpledb.JSimpleDB.createTransaction(JSimpleDB.java:581)
    	at org.jsimpledb.JSimpleDB.createTransaction(JSimpleDB.java:551)
    

    So I can't see an example of how to programmatically start BDB via JSimpleDB, and don't know what to do next to get it going. What am I doing wrong?

    Oh, and it would be cool to have fluent interfaces like withDirectory() and withDatabaseName() for in-line fun:

    jdb = new JSimpleDBFactory()
        .setDatabase(new Database(new BerkeleyKVDatabase()
            .withDirectory(new File(".")).withDatabaseName("fred")))
        .setSchemaVersion(-1)
        .setModelClasses(Person.class).newJSimpleDB();
    
    opened by paul-hammant 7
  • Convert build from ant to Maven

    Convert build from ant to Maven

    Maven pom's are an ide agnostic way of sharing project.

    The maven pom is unusable jsimpledb/src/mvn/pom.xml

    The pom.xml can not be imported into an ide.

    opened by malcolm-davis 7
  • Playing well with other libraries like Jackson for serialization

    Playing well with other libraries like Jackson for serialization

    For modern web frameworks, JSON can be made automatically for return values from method invocation that are bound to HTTP-GET operations. For example List<Person> can be turned into a list a people in JSON.

    Strategies are needed for excluding the fields from the JSimpleDB generated subclass of Person though. If the serialization tech is Jackson, there are a number of strategies but each is quite a bit of obscure code. Especially if the web-framework in question instantiates its own ObjectMapper.

    Jackson allows @JsonIgnore to prefix any field that should not be serialized. Java is quite generous for annotations that are missing from the classpath at runtime so adding that to every @JsimpleDB generated field would work.

    Alternatively (and best of all) making each @JsimpleDB generated field transient would work too. This one would work for Gson too.

    Thoughts?

    opened by paul-hammant 6
  • Verify SQL Server properly compares binary values

    Verify SQL Server properly compares binary values

    Does SQL Server consider 0x1234 equal to 0x123400 ?

    This is of course incompatible with JSimpleDB's assumptions about key/value stores and would mean MSSQLKVDatabase is broken, even though it appears to pass the unit tests OK (in my tests).

    Some worrisome data points:

    http://stackoverflow.com/questions/26255195/how-does-varbinary-data-sorted/26257328?noredirect=1#comment74644636_26257328

    https://dba.stackexchange.com/questions/48660/comparing-binary-0x-and-0x00-turns-out-to-be-equal-on-sql-server

    opened by archiecobbs 5
  • Auto-boxing equivalent required for Kotlin compatibility

    Auto-boxing equivalent required for Kotlin compatibility

    Kotlin unifies int and java.lang.Integer at the language level. Likewise for other primitives. This confuses JSimpleDB and yields errors like this one:

    Exception in thread "main" java.lang.IllegalArgumentException: invalid value type int for index query on field `age' in class net.plan99.jsimdb.Person: should be a super-type of java.lang.Integer

    given this sort of code:

    fun queryByAge() = dbtx.queryIndex(Person::class.java, "age", Int::class.java).asMap()

    It works if I change it to:

    fun queryByAge() = dbtx.queryIndex(Person::class.java, "age", Integer::class.java).asMap()

    but this triggers Kotlin warnings and really, it'd be nicer if int and Integer were treated as equivalent.

    opened by mikehearn 4
  • Weirdness for POJO field access

    Weirdness for POJO field access

    Here's my POJO with annotations added for JSimpleDB:

    @JSimpleClass
    public class Person {
    
    	private int id;
    	private String name;
    	private String email;
    	private int age;
    
    	@JField(indexed = true)
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	@JField
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	@JField
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
    
    	@JField
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public void updateWith(Person upToDatePerson) {
    		this.age = upToDatePerson.age;
    		this.email = upToDatePerson.email;
    		this.name = upToDatePerson.name;
    	}
    
    //	@Override
    //	public String toString() {
    //		return "Person{" +
    //				"id=" + id +
    //				", name='" + name + '\'' +
    //				", email='" + email + '\'' +
    //				", age=" + age +
    //				'}';
    //	}
    
    	@Override
    	public String toString() {
    		return "Person{" +
    				"id=" + getId() +
    				", name='" + getName() + '\'' +
    				", email='" + getEmail() + '\'' +
    				", age=" + getAge() +
    				'}';
    	}
    }
    

    There's two alternate toString() implementations there. One that Intellij made for me that uses fields to compose the RV. In use those were 0 and null despite prior setXyz() calls on the instance. When I changed it to use the getters it worked as expected. I deduce that the POJOs own fields are effectively disabled. While I understand that JSimpleDB wants to subclass POJOs, I feel it could be more faithful to the definition of POJOs if each generated method were to also invoke the super with the same args.

    Or give up on POJOs and suggest abstractions only.

    The trouble with the latter is that web frameworks like Spring want to create a temp 'model' object from request params (and cookie vars and form fields) to hand to a controller method, and according to MVC* that model object could be discarded and not at all saved - subject to the control flow within the controller method (and whatever collaborating methods it calls). Given 'not save' is a viable lifecycle for a Person instance (in this case) that'd be coming through a web-UI, then we cannot insist that all Person instances are made via JTransaction.create(modelClass). If we did it would be data-binding*.

    Say we did insist that. I'd end up with Person.class for saving to JSimpleDB, and PersonUI.class with all the same fields and methods for the UI framework to casually create at will, and a checklist activity for the dev team to ensure that the two Person classes tracked each other's fields etc over the months and years. Or a code gen situation.

    * https://paulhammant.com/2015/04/29/mvc-misunderstood-for-37-years - find "Late to MVC Party" in page

    opened by paul-hammant 4
  • Infinite Loop with 'Hello World' code in SQLKVDatabase

    Infinite Loop with 'Hello World' code in SQLKVDatabase

    First I've got to say, this looks like a really awesome project!

    I'm hoping to use it in a new project, but for a database I'm required to use MS SQL 2012, and I encountered an infinite loop.

    To get started, I pulled the required jars for jsimpledb-kv-3.4.0, and I fetched the latest JTDS/MS drivers. I then followed the instructions at the getting started page. I first ran everything with the XMLKVDatabase and had no issues.

    I then extended the SQLKVDatabase to override createPutStatement() with a transaction. Writing works, but during the read I ran into the loop at getFriendsToMe().

    I overrode createGetRangeStatement() and changed the range from column>=? to column>?, and then received the expected output without any issue.

    Do you believe this problem is specific to MS SQL? And is there a test procedure I should use to ensure interoperability with the database?

    opened by Smorgasbordq 4
  • AccessDeniedException on AtomicArrayKVStore initialization.

    AccessDeniedException on AtomicArrayKVStore initialization.

    Whether you can open a directory as a regular file is highly platform specific. The following code fails on Windows.

    Offending code:

    if(!this.directory.isDirectory()) {
        throw new ArrayKVException("file `" + this.directory + "\' is not a directory");
    }
    this.directoryChannel = FileChannel.open(this.directory.toPath(), new OpenOption[0]);
    

    Stacktrace: Caused by: java.nio.file.AccessDeniedException: C:\x\y\z\kvstore at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) at sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:115) at java.nio.channels.FileChannel.open(FileChannel.java:287) at java.nio.channels.FileChannel.open(FileChannel.java:335) at org.jsimpledb.kv.array.AtomicArrayKVStore.start(AtomicArrayKVStore.java:353) ... 72 more

    opened by mooreba 4
  • Miscellaneous typo/JavaDoc fixes, small code simplifications, add IntellliJ files to .gitignore

    Miscellaneous typo/JavaDoc fixes, small code simplifications, add IntellliJ files to .gitignore

    I've spent a lot of time over the holiday break reading and understanding some of the Permazen code. As part of that I fixed a bunch of typos, broken JavaDocs etc that IntelliJ flagged. I also accepted a few of its suggestions for code simplification, albeit not most of them to avoid too much pointless churn.

    Where code has been deleted it's because it's dead. I left most dead methods as they may be useful in future, but some stuff would clearly never be used.

    opened by mikehearn 3
  • Bump jetty-server from 9.4.44.v20210927 to 10.0.10

    Bump jetty-server from 9.4.44.v20210927 to 10.0.10

    Bumps jetty-server from 9.4.44.v20210927 to 10.0.10.

    Release notes

    Sourced from jetty-server's releases.

    10.0.10

    Special Thanks to the following Eclipse Jetty community members

    Changelog

    • #8136 - Cherry-pick of Improvements to PathSpec for Jetty 10.0.x
    • #8134 - Improve cleanup of deflater/inflater pools for PerMessageDeflateExtension
    • #8088 - Add option to configure exitVm on ShutdownMonitor from System properties
    • #8067 - Wall time usage in DoSFilter RateTracker results in false positive alert
    • #8057 - Support Http Response 103 (Early Hints)
    • #8014 - Review HttpRequest URI construction
    • #8008 - Add compliance mode for LEGACY multipart parser in Jetty 10+
    • #7994 - Ability to construct a detached client Request
    • #7981 - Add TRANSFER_ENCODING violation for MultiPart RFC7578 parser. (#7976)
    • #7977 - UpgradeHttpServletRequest.setAttribute & UpgradeHttpServletRequest.removeAttribute can throw NullPointerException
    • #7975 - ForwardedRequestCustomizer setters do not clear existing handlers
    • #7953 - Fix StatisticsHandler in the case a Handler throws exception.
    • #7935 - Review HTTP/2 error handling
    • #7929 - Correct requestlog formatString commented default (@​prenagha)
    • #7924 - Fix a typo in Javadoc (@​jianglai)
    • #7918 - PathMappings.asPathSpec does not allow root ServletPathSpec
    • #7891 - Better Servlet PathMappings for Regex
    • #7880 - DefaultServlet should not overwrite programmatically configured precompressed formats with defaults (@​markslater)
    • #7863 - Default servlet drops first accept-encoding header if there is more than one. (@​markslater)
    • #7858 - GZipHandler does not play nice with other handlers in HandlerCollection
    • #7818 - Modifying of HTTP headers in HttpChannel.Listener#onResponseBegin is no longer possible with Jetty 10
    • #7808 - Jetty 10.0.x 7801 duplicate set session cookie
    • #7802 - HTTP/3 QPACK - do not expect section ack for zero required insert count
    • #7754 - jetty.sh ignores JAVA_OPTIONS environment variable
    • #7748 - Allow overriding of url-pattern mapping in ServletContextHandler to allow for regex or uri-template matching
    • #7635 - QPACK decoder should fail connection if the encoder blocks more than SETTINGS_QPACK_BLOCKED_STREAMS
    • #4414 - GZipHandler not excluding inflation for specified paths
    • #1771 - Add module for SecuredRedirect support

    Dependencies

    • #8083 - Bump asciidoctorj to 2.5.4
    • #8077 - Bump asciidoctorj-diagram to 2.2.3
    • #7839 - Bump asm.version to 9.3
    • #8142 - Bump biz.aQute.bndlib to 6.3.1
    • #8075 - Bump checkstyle to 10.3
    • #8056 - Bump error_prone_annotations to 2.14.0
    • #8109 - Bump google-cloud-datastore to 2.7.0
    • #8100 - Bump grpc-core to 1.47.0
    • #7987 - Bump hawtio-default to 2.15.0

    ... (truncated)

    Commits
    • de73e94 Updating to version 10.0.10
    • 1b4f941 RegexPathSpec documentation and MatchedPath improvements (#8163)
    • 1f902f6 Disable H3 tests by default with a system property to explicitly enable them ...
    • 7cc461b Fixing javadoc build errors (#8173)
    • d63569d Migrate code from jetty-util Logger to slf4j Logger (#8162)
    • 66de7ba Improve ssl buffers handling (#8165)
    • 0699bc5 Use static exceptions for closing websocket flushers and in ContentProducer (...
    • b1c19c0 Merge pull request #8134 from eclipse/jetty-10.0.x-websocketPermessageDeflate...
    • 23948f1 no more profile IT tests runs per default (#8138)
    • 0d13cbe change-dependabot-interval-to-monthly (#8140)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • Bump spring-web from 5.3.20 to 6.0.0

    Bump spring-web from 5.3.20 to 6.0.0

    Bumps spring-web from 5.3.20 to 6.0.0.

    Release notes

    Sourced from spring-web's releases.

    v6.0.0

    See What's New in Spring Framework 6.x and Upgrading to Spring Framework 6.x for upgrade instructions and details of new features.

    :star: New Features

    • Avoid direct URL construction and URL equality checks #29486
    • Simplify creating RFC 7807 responses from functional endpoints #29462
    • Allow test classes to provide runtime hints via declarative mechanisms #29455

    :notebook_with_decorative_cover: Documentation

    • Align javadoc of DefaultParameterNameDiscoverer with its behavior #29494
    • Document AOT support in the TestContext framework #29482
    • Document Ahead of Time processing in the reference guide #29350

    :hammer: Dependency Upgrades

    • Upgrade to Reactor 2022.0.0 #29465

    :heart: Contributors

    Thank you to all the contributors who worked on this release:

    @​ophiuhus and @​wilkinsona

    v6.0.0-RC4

    :star: New Features

    • Introduce DataFieldMaxValueIncrementer for SQL Server sequences #29447
    • Introduce findAllAnnotationsOnBean variant on ListableBeanFactory #29446
    • Introduce support for Jakarta WebSocket 2.1 #29436
    • Allow @ControllerAdvice in WebFlux to handle exceptions before a handler is selected #22991

    :lady_beetle: Bug Fixes

    • Bean with unresolved generics do not use fallback algorithms with AOT #29454
    • TomcatRequestUpgradeStrategy is not compatible with Tomcat 10.1 #29434
    • Autowiring of a generic type produced by a factory bean fails after AOT processing #29385

    :notebook_with_decorative_cover: Documentation

    • Reference PDF containing full docs not available #28451

    :hammer: Dependency Upgrades

    • Revisit Servlet API baseline: Servlet 6.0 in the build, Servlet 5.0 compatibility at runtime #29435
    • Upgrade to Context Propagation 1.0.0 #29442
    • Upgrade to Jackson 2.14.0 #29351
    • Upgrade to Micrometer 1.10.0 #29441

    ... (truncated)

    Commits
    • 5a30a43 Release v6.0.0
    • 42856ba Add milestone repo for optional Netty 5 support
    • 9be6cea Polishing deprecated methods
    • 37b4391 Align javadoc of DefaultParameterNameDiscoverer with its behavior
    • 09a58a5 Polish
    • 10f4ad1 Assert fixed in DefaultErrorResponseBuilder
    • 9457ed3 Document AOT support in the TestContext framework
    • 074ec97 Fix section formatting in the testing chapter
    • 9ede4af Revert "Ignore HttpComponents Javadoc"
    • bfc1251 Merge branch '5.3.x'
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Cohesive examples needed and information architecture.

    Cohesive examples needed and information architecture.

    Examples

    Unit tests don't give enough info for the end-user to get up and running with. Consider BDB. There should perhaps be a README in here - https://github.com/archiecobbs/jsimpledb/tree/master/jsimpledb-kv-bdb. From that links to example projects.

    Implementations

    Note too that https://github.com/archiecobbs/jsimpledb (readme) does not mention Berkeley. First linked wiki page Information does, but that links to JavaDocs. One third of the dev world is happy with ref docs, one third with tutorials and one third cohesive examples (like me). Note that StackOverflow is Mecca for example-code people (I have your JSimpleDB answers an upvote).

    The unit test for the bdb implementation doesn't yield any larger "how to" information. Nor does the CLI tool.

    By contrast, the Jooby project provides a number of cohesive example applications, complete with build unit test and integration tests. Like this one - https://github.com/jooby-project/greeting. Easy to use as a starting point for your own app.

    Information rift:

    • the Introduction wiki page (listed first) shows snippets of key and value interop.
    • the getting started wiki page (listed second) shows wrapping JDB setup and try/finally stuff that must wrap all snippets. Cruicial, IMO, is the usage of .newJSimpleDB() but there's only two refs to that in that page, and not at the top. Note also, you've two orphaned </code> markup vestiges in that doc to excise.
    • There should be a wiki page that lists all the implementations of JSimpleDB, including the BDB one. It should be listed in the readme, and linked to again in Introduction and Getting Started. That should include the differentiating setup per implementation.
    • .start() and .stop are not really discussed anywhere. Why? What if I don't stop the DB before shutdown? Why can't it start itself on first use?

    Don't be put off - I think your stuff is great - and my nooooob experience report should be useful to you.

    opened by paul-hammant 3
  • Vaadin GUI Update

    Vaadin GUI Update

    This isn't an issue per say, but after setting up the GUI editor for a schema I wrote, I realized I was no longer able to edit objects with a Set, since the JSet/JMap/JList field builders in JObjectEditorWindow.java are still a TODO and result in an "Invalid value(s)" message.

    Though technically not needed, I'd really love to use the editor. Any recommendation to get past this in the meantime? Alternatively, I'm thinking I could hold myself over by writing a very simple implementation of the field builders (a text field of json to represent the set/map/list of either internal IDs or simple data)

    opened by Smorgasbordq 1
Owner
Permazen
Language-Natural Persistence Layer for Java
Permazen
MyBatis SQL mapper framework for Java

MyBatis SQL Mapper Framework for Java The MyBatis SQL mapper framework makes it easier to use a relational database with object-oriented applications.

MyBatis 18k Jan 2, 2023
Fast and Easy mapping from database and csv to POJO. A java micro ORM, lightweight alternative to iBatis and Hibernate. Fast Csv Parser and Csv Mapper

Simple Flat Mapper Release Notes Getting Started Docs Building it The build is using Maven. git clone https://github.com/arnaudroger/SimpleFlatMapper.

Arnaud Roger 418 Dec 17, 2022
ObjectiveSQL is an ORM framework in Java based on ActiveRecord pattern

ObjectiveSQL is an ORM framework in Java based on ActiveRecord pattern, which encourages rapid development and clean, codes with the least, and convention over configuration.

Braisdom 1.2k Dec 28, 2022
Storm - a fast, easy to use, no-bullshit opinionated Java ORM inspired by Doctrine

A stupidly simple Java/MySQL ORM with native Hikaricp and Redis cache support supporting MariaDB and Sqlite

Mats 18 Dec 1, 2022
ORM16 is a library exploring code generation-based approach to ORM for Java 17 and focusing on records as persistent data model

About ORM16 ORM16 is a library exploring code generation-based approach to ORM for Java 17 and focusing on records as persistent data model. Example I

Ivan Gammel 1 Mar 30, 2022
👄 The most accurate natural language detection library for Java and the JVM, suitable for long and short text alike

Quick Info this library tries to solve language detection of very short words and phrases, even shorter than tweets makes use of both statistical and

Peter M. Stahl 532 Dec 28, 2022
MALLET is a Java-based package for statistical natural language processing, document classification, clustering, topic modeling, information extraction, and other machine learning applications to text.

MALLET is a Java-based package for statistical natural language processing, document classification, clustering, topic modeling, information extraction, and other machine learning applications to text.

null 900 Jan 2, 2023
CogComp's Natural Language Processing libraries and Demos:

CogCompNLP This project collects a number of core libraries for Natural Language Processing (NLP) developed by Cognitive Computation Group. How to use

CogComp 457 Dec 20, 2022
Apache OpenNLP library is a machine learning based toolkit for the processing of natural language text

Welcome to Apache OpenNLP! The Apache OpenNLP library is a machine learning based toolkit for the processing of natural language text. This toolkit is

The Apache Software Foundation 1.2k Dec 29, 2022
For English vocabulary analysis and sentence analysis in natural language, model trainin

Sword Come ?? For English vocabulary analysis and sentence analysis in natural language, model training, intelligent response and emotion analysis rea

James Zow 2 Apr 9, 2022
lazy-language-loader improves loading times when changing your language by only reloading the language instead of all the game resources!

lazy-language-loader lazy-language-loader improves loading times when changing your language by only reloading the language instead of all the game re

Shalom Ademuwagun 7 Sep 7, 2022
requery - modern SQL based query & persistence for Java / Kotlin / Android

A light but powerful object mapping and SQL generator for Java/Kotlin/Android with RxJava and Java 8 support. Easily map to or create databases, perfo

requery 3.1k Jan 5, 2023
Microstream - High-Performance Java-Native-Persistence

Microstream - High-Performance Java-Native-Persistence. Store and load any Java Object Graph or Subgraphs partially, Relieved of Heavy-weight JPA. Microsecond Response Time. Ultra-High Throughput. Minimum of Latencies. Create Ultra-Fast In-Memory Database Applications & Microservices.

MicroStream 410 Dec 28, 2022
Flash cards app using JavaFX, Scene Builder and persistence using Serialization with JAVA IO API

Flashcards - JavaFX , Scene Builder, Serialized Persistence JAVA IO API Main Scene that will show all the Decks in Flash Card App Add or Edit Cards in

Ali Raja 3 Nov 28, 2022
The High-Performance Java Persistence book and video course code examples

High-Performance Java Persistence The High-Performance Java Persistence book and video course code examples. I wrote this article about this repositor

Vlad Mihalcea 1.1k Jan 9, 2023
Apache Cayenne is an open source persistence framework licensed under the Apache License

Apache Cayenne is an open source persistence framework licensed under the Apache License, providing object-relational mapping (ORM) and remoting services.

The Apache Software Foundation 284 Dec 31, 2022
Makes fire created by natural lightning cosmetic, meaning no blocks are destroyed from bad weather

Lightning Podoboo Makes fire created by natural lightning cosmetic, meaning no blocks are destroyed from bad weather. Keep the doFireTick gamerule ena

Lilly Rose Berner 10 Dec 15, 2022
Kotlin-decompiled - (Almost) every single language construct of the Kotlin programming language compiled to JVM bytecode and then decompiled to Java again for better readability

Kotlin: Decompiled (Almost) every single language construct of the Kotlin programming language compiled to JVM bytecode and then decompiled to Java ag

The Self-Taught Software Engineer 27 Dec 14, 2022
This application can recognize the sign language alphabets and help people who do not understand sign language to communicate with the speech and hearing impaired.

Sign Language Recognition App This application can recognize the sign language alphabets and help people who do not understand sign language to commun

Mihir Gandhi 12 Oct 7, 2021