This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 5e83eb5bfc Databasejoin to support caching mechanism #3810 (#3822)
5e83eb5bfc is described below

commit 5e83eb5bfcd9594697094f237738e92498b09d7a
Author: Sergio De Lorenzis <[email protected]>
AuthorDate: Fri Apr 26 14:04:29 2024 +0200

    Databasejoin to support caching mechanism #3810 (#3822)
    
    * Cache lookup rows for performance reason
    
    * Apply spotless, #3810
    
    ---------
    
    Co-authored-by: Hans Van Akelyen <[email protected]>
---
 .../transforms/databasejoin/databasejoin-grid.png  | Bin 58786 -> 70182 bytes
 .../pages/pipeline/transforms/databasejoin.adoc    |  11 +-
 .../0009-database-join-cache-large-enough.hpl      | 265 ++++++++++++++++++++
 .../0009-database-join-cache-undersized.hpl        | 269 ++++++++++++++++++++
 .../0009-database-join-cache-unlimited-size.hpl    | 265 ++++++++++++++++++++
 .../database/main-0009-database-join.hwf           | 270 +++++++++++++++++----
 integration-tests/database/scripts/script2.sql     |  20 ++
 .../transforms/databasejoin/DatabaseJoin.java      |  81 ++++---
 .../transforms/databasejoin/DatabaseJoinData.java  |   3 +
 .../databasejoin/DatabaseJoinDialog.java           |  64 ++++-
 .../transforms/databasejoin/DatabaseJoinMeta.java  |  43 ++++
 .../databasejoin/cache/DatabaseCache.java          |  69 ++++++
 .../messages/messages_de_DE.properties             |  34 +--
 .../messages/messages_en_US.properties             |  36 +--
 .../messages/messages_es_AR.properties             |  28 ++-
 .../messages/messages_es_ES.properties             |  30 ++-
 .../messages/messages_fr_FR.properties             |  30 ++-
 .../messages/messages_it_IT.properties             |  36 +--
 .../messages/messages_ja_JP.properties             |  20 +-
 .../messages/messages_ko_KR.properties             |  14 +-
 .../messages/messages_pt_BR.properties             |  31 +--
 .../messages/messages_pt_PT.properties             |  30 +--
 .../messages/messages_zh_CN.properties             |  26 +-
 23 files changed, 1464 insertions(+), 211 deletions(-)

diff --git 
a/docs/hop-user-manual/modules/ROOT/assets/images/transforms/databasejoin/databasejoin-grid.png
 
b/docs/hop-user-manual/modules/ROOT/assets/images/transforms/databasejoin/databasejoin-grid.png
index 4f8e458599..9107792158 100644
Binary files 
a/docs/hop-user-manual/modules/ROOT/assets/images/transforms/databasejoin/databasejoin-grid.png
 and 
b/docs/hop-user-manual/modules/ROOT/assets/images/transforms/databasejoin/databasejoin-grid.png
 differ
diff --git 
a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/databasejoin.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/databasejoin.adoc
index c940eb577e..f1b11039cc 100644
--- 
a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/databasejoin.adoc
+++ 
b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/databasejoin.adoc
@@ -74,9 +74,18 @@ To define and use multiple parameters, list the fields in 
order you want them to
 |Option|Description
 |Transform name|Name of the transform; This name has to be unique in a single 
pipeline
 |Connection|The database connection to use for the query.
+|Enable cache?|Enables caching of database lookups.
+This means that once a key (or group of key) has been looked up, the looked up 
values are stored, and returned again the next time this key (or group of key) 
is being looked up (without incurring the cost of a database call).
+
+*Important*: If other processes are changing values in the table where you 
perform a lookup, do not cache values.
+In all other instances, caching values increases the performance substantially 
because database lookups are relatively slow.
+If you can't use the cache, consider launching several copies of the 
simultaneously.
+A simultaneous launch keeps the database busy through different connections.
+See Launching several copies of a transform.
+|Cache size in rows|The size of the cache (number of rows), 0 means cache 
everything.
 |SQL|SQL query to form the join; use question marks as parameter placeholders
 |Number of rows to return|Zero (0) returns all rows; any other number limits 
the number of rows returned.
 |Outer join?|Enable to always return a result, even if the query did not 
return a result
 |Parameters table|Specify the fields containing parameters.
 The parameter type is required.
-|===
\ No newline at end of file
+|===
diff --git 
a/integration-tests/database/0009-database-join-cache-large-enough.hpl 
b/integration-tests/database/0009-database-join-cache-large-enough.hpl
new file mode 100644
index 0000000000..1d30a4613a
--- /dev/null
+++ b/integration-tests/database/0009-database-join-cache-large-enough.hpl
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+  <info>
+    <name>0009-database-join-cache-large-enough</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description/>
+    <extended_description/>
+    <pipeline_version/>
+    <pipeline_type>Normal</pipeline_type>
+    <parameters>
+    </parameters>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <created_user>-</created_user>
+    <created_date>2024/04/12 13:08:01.206</created_date>
+    <modified_user>-</modified_user>
+    <modified_date>2024/04/12 13:08:01.206</modified_date>
+  </info>
+  <notepads>
+  </notepads>
+  <order>
+    <hop>
+      <from>Database join - cache of size very big</from>
+      <to>count rows</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>Generate Rows</from>
+      <to>Database join - cache of size very big</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>count rows</from>
+      <to>validate count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>failed on count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>success</to>
+      <enabled>Y</enabled>
+    </hop>
+  </order>
+  <transform>
+    <name>Database join - cache of size very big</name>
+    <type>DBJoin</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <cache>Y</cache>
+    <cache_size>200</cache_size>
+    <connection>unit-test-db-generic</connection>
+    <outer_join>N</outer_join>
+    <parameter>
+      <field>
+        <name>name</name>
+        <type>String</type>
+      </field>
+    </parameter>
+    <replace_vars>Y</replace_vars>
+    <rowlimit>0</rowlimit>
+    <sql>select id, name, description from public.foo
+where name = ?</sql>
+    <attributes/>
+    <GUI>
+      <xloc>448</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Generate Rows</name>
+    <type>DataGrid</type>
+    <description/>
+    <distribute>N</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <data>
+      <line>
+        <item>Alice</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Alice</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>name</name>
+        <type>String</type>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>192</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>count rows</name>
+    <type>GroupBy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <add_linenr>N</add_linenr>
+    <all_rows>N</all_rows>
+    <directory>${java.io.tmpdir}</directory>
+    <fields>
+      <field>
+        <aggregate>count</aggregate>
+        <type>COUNT_ANY</type>
+      </field>
+    </fields>
+    <give_back_row>Y</give_back_row>
+    <group>
+</group>
+    <ignore_aggregate>N</ignore_aggregate>
+    <prefix>grp</prefix>
+    <attributes/>
+    <GUI>
+      <xloc>640</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>failed on count</name>
+    <type>Abort</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <abort_option>ABORT_WITH_ERROR</abort_option>
+    <always_log_rows>Y</always_log_rows>
+    <row_threshold>0</row_threshold>
+    <attributes/>
+    <GUI>
+      <xloc>752</xloc>
+      <yloc>192</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>success</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>896</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>validate count</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <compare>
+      <condition>
+        <conditions>
+</conditions>
+        <function>=</function>
+        <leftvalue>count</leftvalue>
+        <negated>N</negated>
+        <operator>-</operator>
+        <value>
+          <isnull>N</isnull>
+          <length>-1</length>
+          <mask>####0;-####0</mask>
+          <name>constant</name>
+          <precision>0</precision>
+          <text>32</text>
+          <type>Integer</type>
+        </value>
+      </condition>
+    </compare>
+    <send_false_to>failed on count</send_false_to>
+    <send_true_to>success</send_true_to>
+    <attributes/>
+    <GUI>
+      <xloc>752</xloc>
+      <yloc>96</yloc>
+    </GUI>
+  </transform>
+  <transform_error_handling>
+  </transform_error_handling>
+  <attributes/>
+</pipeline>
diff --git a/integration-tests/database/0009-database-join-cache-undersized.hpl 
b/integration-tests/database/0009-database-join-cache-undersized.hpl
new file mode 100644
index 0000000000..21a1664c2f
--- /dev/null
+++ b/integration-tests/database/0009-database-join-cache-undersized.hpl
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+  <info>
+    <name>0009-database-join-cache-undersized</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description/>
+    <extended_description/>
+    <pipeline_version/>
+    <pipeline_type>Normal</pipeline_type>
+    <parameters>
+    </parameters>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <created_user>-</created_user>
+    <created_date>2024/04/12 13:08:01.206</created_date>
+    <modified_user>-</modified_user>
+    <modified_date>2024/04/12 13:08:01.206</modified_date>
+  </info>
+  <notepads>
+  </notepads>
+  <order>
+    <hop>
+      <from>Database join - cache of size 2</from>
+      <to>count rows</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>Generate Rows</from>
+      <to>Database join - cache of size 2</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>count rows</from>
+      <to>validate count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>failed on count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>success</to>
+      <enabled>Y</enabled>
+    </hop>
+  </order>
+  <transform>
+    <name>Database join - cache of size 2</name>
+    <type>DBJoin</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <cache>Y</cache>
+    <cache_size>2</cache_size>
+    <connection>unit-test-db-generic</connection>
+    <outer_join>N</outer_join>
+    <parameter>
+      <field>
+        <name>name</name>
+        <type>String</type>
+      </field>
+    </parameter>
+    <replace_vars>Y</replace_vars>
+    <rowlimit>0</rowlimit>
+    <sql>select id, name, description from public.foo
+where name = ?</sql>
+    <attributes/>
+    <GUI>
+      <xloc>1472</xloc>
+      <yloc>496</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Generate Rows</name>
+    <type>DataGrid</type>
+    <description/>
+    <distribute>N</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <data>
+      <line>
+        <item>Alice</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Alice</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <currency/>
+        <set_empty_string>N</set_empty_string>
+        <name>name</name>
+        <format/>
+        <group/>
+        <decimal/>
+        <type>String</type>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>1216</xloc>
+      <yloc>496</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>count rows</name>
+    <type>GroupBy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <add_linenr>N</add_linenr>
+    <all_rows>N</all_rows>
+    <directory>${java.io.tmpdir}</directory>
+    <fields>
+      <field>
+        <aggregate>count</aggregate>
+        <type>COUNT_ANY</type>
+      </field>
+    </fields>
+    <give_back_row>Y</give_back_row>
+    <group>
+</group>
+    <ignore_aggregate>N</ignore_aggregate>
+    <prefix>grp</prefix>
+    <attributes/>
+    <GUI>
+      <xloc>1664</xloc>
+      <yloc>496</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>failed on count</name>
+    <type>Abort</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <abort_option>ABORT_WITH_ERROR</abort_option>
+    <always_log_rows>Y</always_log_rows>
+    <row_threshold>0</row_threshold>
+    <attributes/>
+    <GUI>
+      <xloc>1776</xloc>
+      <yloc>592</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>success</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>1920</xloc>
+      <yloc>496</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>validate count</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <compare>
+      <condition>
+        <conditions>
+</conditions>
+        <function>=</function>
+        <leftvalue>count</leftvalue>
+        <negated>N</negated>
+        <operator>-</operator>
+        <value>
+          <isnull>N</isnull>
+          <length>-1</length>
+          <mask>####0;-####0</mask>
+          <name>constant</name>
+          <precision>0</precision>
+          <text>32</text>
+          <type>Integer</type>
+        </value>
+      </condition>
+    </compare>
+    <send_false_to>failed on count</send_false_to>
+    <send_true_to>success</send_true_to>
+    <attributes/>
+    <GUI>
+      <xloc>1776</xloc>
+      <yloc>496</yloc>
+    </GUI>
+  </transform>
+  <transform_error_handling>
+  </transform_error_handling>
+  <attributes/>
+</pipeline>
diff --git 
a/integration-tests/database/0009-database-join-cache-unlimited-size.hpl 
b/integration-tests/database/0009-database-join-cache-unlimited-size.hpl
new file mode 100644
index 0000000000..b7b0e5f32b
--- /dev/null
+++ b/integration-tests/database/0009-database-join-cache-unlimited-size.hpl
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+  <info>
+    <name>0009-database-join-cache-unlimited-size</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description/>
+    <extended_description/>
+    <pipeline_version/>
+    <pipeline_type>Normal</pipeline_type>
+    <parameters>
+    </parameters>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <created_user>-</created_user>
+    <created_date>2024/04/12 13:08:01.206</created_date>
+    <modified_user>-</modified_user>
+    <modified_date>2024/04/12 13:08:01.206</modified_date>
+  </info>
+  <notepads>
+  </notepads>
+  <order>
+    <hop>
+      <from>Database join - cache of unlimited size enabled</from>
+      <to>count rows</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>count rows</from>
+      <to>validate count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>failed on count</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>validate count</from>
+      <to>success</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>Generate Rows</from>
+      <to>Database join - cache of unlimited size enabled</to>
+      <enabled>Y</enabled>
+    </hop>
+  </order>
+  <transform>
+    <name>Database join - cache of unlimited size enabled</name>
+    <type>DBJoin</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <cache>Y</cache>
+    <cache_size>0</cache_size>
+    <connection>unit-test-db-generic</connection>
+    <outer_join>N</outer_join>
+    <parameter>
+      <field>
+        <name>name</name>
+        <type>String</type>
+      </field>
+    </parameter>
+    <replace_vars>Y</replace_vars>
+    <rowlimit>0</rowlimit>
+    <sql>select id, name, description from public.foo
+where name = ?</sql>
+    <attributes/>
+    <GUI>
+      <xloc>512</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>Generate Rows</name>
+    <type>DataGrid</type>
+    <description/>
+    <distribute>N</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <data>
+      <line>
+        <item>Alice</item>
+      </line>
+      <line>
+        <item>Alice</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Bob</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+      <line>
+        <item>Charlie</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>name</name>
+        <type>String</type>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>256</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>count rows</name>
+    <type>GroupBy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <add_linenr>N</add_linenr>
+    <all_rows>N</all_rows>
+    <directory>${java.io.tmpdir}</directory>
+    <fields>
+      <field>
+        <aggregate>count</aggregate>
+        <type>COUNT_ANY</type>
+      </field>
+    </fields>
+    <give_back_row>Y</give_back_row>
+    <group>
+</group>
+    <ignore_aggregate>N</ignore_aggregate>
+    <prefix>grp</prefix>
+    <attributes/>
+    <GUI>
+      <xloc>704</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>failed on count</name>
+    <type>Abort</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <abort_option>ABORT_WITH_ERROR</abort_option>
+    <always_log_rows>Y</always_log_rows>
+    <row_threshold>0</row_threshold>
+    <attributes/>
+    <GUI>
+      <xloc>816</xloc>
+      <yloc>240</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>success</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>960</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>validate count</name>
+    <type>FilterRows</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <compare>
+      <condition>
+        <conditions>
+</conditions>
+        <function>=</function>
+        <leftvalue>count</leftvalue>
+        <negated>N</negated>
+        <operator>-</operator>
+        <value>
+          <isnull>N</isnull>
+          <length>-1</length>
+          <mask>####0;-####0</mask>
+          <name>constant</name>
+          <precision>0</precision>
+          <text>32</text>
+          <type>Integer</type>
+        </value>
+      </condition>
+    </compare>
+    <send_false_to>failed on count</send_false_to>
+    <send_true_to>success</send_true_to>
+    <attributes/>
+    <GUI>
+      <xloc>816</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform_error_handling>
+  </transform_error_handling>
+  <attributes/>
+</pipeline>
diff --git a/integration-tests/database/main-0009-database-join.hwf 
b/integration-tests/database/main-0009-database-join.hwf
index 452a1a6681..9c5bc88d19 100644
--- a/integration-tests/database/main-0009-database-join.hwf
+++ b/integration-tests/database/main-0009-database-join.hwf
@@ -35,14 +35,14 @@ limitations under the License.
       <description/>
       <type>SPECIAL</type>
       <attributes/>
-      <repeat>N</repeat>
-      <schedulerType>0</schedulerType>
-      <intervalSeconds>0</intervalSeconds>
-      <intervalMinutes>60</intervalMinutes>
+      <DayOfMonth>1</DayOfMonth>
       <hour>12</hour>
+      <intervalMinutes>60</intervalMinutes>
+      <intervalSeconds>0</intervalSeconds>
       <minutes>0</minutes>
+      <repeat>N</repeat>
+      <schedulerType>0</schedulerType>
       <weekDay>1</weekDay>
-      <DayOfMonth>1</DayOfMonth>
       <parallel>N</parallel>
       <xloc>64</xloc>
       <yloc>48</yloc>
@@ -53,12 +53,11 @@ limitations under the License.
       <description/>
       <type>SQL</type>
       <attributes/>
-      <sql/>
-      <useVariableSubstitution>F</useVariableSubstitution>
-      <sqlfromfile>T</sqlfromfile>
-      <sqlfilename>${PROJECT_HOME}/scripts/script2.sql</sqlfilename>
-      <sendOneStatement>F</sendOneStatement>
       <connection>unit-test-db</connection>
+      <sendOneStatement>N</sendOneStatement>
+      <sqlfilename>${PROJECT_HOME}/scripts/script2.sql</sqlfilename>
+      <sqlfromfile>Y</sqlfromfile>
+      <useVariableSubstitution>N</useVariableSubstitution>
       <parallel>N</parallel>
       <xloc>208</xloc>
       <yloc>48</yloc>
@@ -69,25 +68,22 @@ limitations under the License.
       <description/>
       <type>PIPELINE</type>
       <attributes/>
-      <filename>${PROJECT_HOME}/0009-database-join-normal.hpl</filename>
-      <params_from_previous>N</params_from_previous>
-      <exec_per_row>N</exec_per_row>
-      <clear_rows>N</clear_rows>
-      <clear_files>N</clear_files>
-      <set_logfile>N</set_logfile>
-      <logfile/>
-      <logext/>
       <add_date>N</add_date>
       <add_time>N</add_time>
-      <loglevel>Basic</loglevel>
-      <set_append_logfile>N</set_append_logfile>
-      <wait_until_finished>Y</wait_until_finished>
-      <follow_abort_remote>N</follow_abort_remote>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
-      <run_configuration>local</run_configuration>
+      <exec_per_row>N</exec_per_row>
+      <filename>${PROJECT_HOME}/0009-database-join-normal.hpl</filename>
+      <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
       </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>local</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
+      <wait_until_finished>Y</wait_until_finished>
       <parallel>N</parallel>
       <xloc>384</xloc>
       <yloc>48</yloc>
@@ -98,25 +94,22 @@ limitations under the License.
       <description/>
       <type>PIPELINE</type>
       <attributes/>
-      <filename>${PROJECT_HOME}/0009-database-join-outer.hpl</filename>
-      <params_from_previous>N</params_from_previous>
-      <exec_per_row>N</exec_per_row>
-      <clear_rows>N</clear_rows>
-      <clear_files>N</clear_files>
-      <set_logfile>N</set_logfile>
-      <logfile/>
-      <logext/>
       <add_date>N</add_date>
       <add_time>N</add_time>
-      <loglevel>Basic</loglevel>
-      <set_append_logfile>N</set_append_logfile>
-      <wait_until_finished>Y</wait_until_finished>
-      <follow_abort_remote>N</follow_abort_remote>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
-      <run_configuration>local</run_configuration>
+      <exec_per_row>N</exec_per_row>
+      <filename>${PROJECT_HOME}/0009-database-join-outer.hpl</filename>
+      <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
       </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>local</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
+      <wait_until_finished>Y</wait_until_finished>
       <parallel>N</parallel>
       <xloc>624</xloc>
       <yloc>48</yloc>
@@ -127,27 +120,176 @@ limitations under the License.
       <description/>
       <type>PIPELINE</type>
       <attributes/>
+      <add_date>N</add_date>
+      <add_time>N</add_time>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
+      <create_parent_folder>N</create_parent_folder>
+      <exec_per_row>N</exec_per_row>
       <filename>${PROJECT_HOME}/0009-database-join-parameter.hpl</filename>
+      <loglevel>Basic</loglevel>
+      <parameters>
+        <pass_all_parameters>Y</pass_all_parameters>
+      </parameters>
       <params_from_previous>N</params_from_previous>
-      <exec_per_row>N</exec_per_row>
-      <clear_rows>N</clear_rows>
+      <run_configuration>local</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
+      <wait_until_finished>Y</wait_until_finished>
+      <parallel>N</parallel>
+      <xloc>864</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>0009-database-join-cache-unlimited-size</name>
+      <description/>
+      <type>PIPELINE</type>
+      <attributes/>
+      <add_date>N</add_date>
+      <add_time>N</add_time>
       <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
+      <create_parent_folder>N</create_parent_folder>
+      <exec_per_row>N</exec_per_row>
+      
<filename>${PROJECT_HOME}/0009-database-join-cache-unlimited-size.hpl</filename>
+      <loglevel>Basic</loglevel>
+      <parameters>
+        <pass_all_parameters>Y</pass_all_parameters>
+      </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>transactional</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
       <set_logfile>N</set_logfile>
-      <logfile/>
-      <logext/>
+      <wait_until_finished>Y</wait_until_finished>
+      <parallel>N</parallel>
+      <xloc>1152</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>Check input rows unlimited cache size</name>
+      <description/>
+      <type>EVAL</type>
+      <attributes/>
+      <script>var inputz = previous_result.getNrLinesInput();
+var expectedInputs = 10;
+var ok=true;
+log.logBasic("Expected 10 inputs from DB, like all the possible values to be 
looked up, and all of them bound to be cached");
+if(inputz == expectedInputs){
+       ok = true;
+       log.logBasic("Got " + inputz + " as expected");
+       
+} else {
+       ok = false;
+       log.logError("Expected " + expectedInputs + ", actual: " + inputz);
+}
+
+ok;</script>
+      <parallel>N</parallel>
+      <xloc>1440</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>0009-database-join-cache-undersized.hpl</name>
+      <description/>
+      <type>PIPELINE</type>
+      <attributes/>
       <add_date>N</add_date>
       <add_time>N</add_time>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
+      <create_parent_folder>N</create_parent_folder>
+      <exec_per_row>N</exec_per_row>
+      
<filename>${PROJECT_HOME}/0009-database-join-cache-undersized.hpl</filename>
       <loglevel>Basic</loglevel>
+      <parameters>
+        <pass_all_parameters>Y</pass_all_parameters>
+      </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>transactional</run_configuration>
       <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
       <wait_until_finished>Y</wait_until_finished>
-      <follow_abort_remote>N</follow_abort_remote>
+      <parallel>N</parallel>
+      <xloc>1744</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>Check input rows limited size</name>
+      <description/>
+      <type>EVAL</type>
+      <attributes/>
+      <script>var inputz = previous_result.getNrLinesInput();
+var expectedInputs = 14;
+var ok=true;
+log.logBasic("Expected to read twice Alice's rows, because of the size of the 
cache");
+if(inputz == expectedInputs){
+       ok = true;
+       log.logBasic("Got " + inputz + " as expected");
+       
+} else {
+       ok = false;
+       log.logError("Expected " + expectedInputs + ", actual: " + inputz);
+}
+
+ok;</script>
+      <parallel>N</parallel>
+      <xloc>2016</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>0009-database-join-cache-large-enough</name>
+      <description/>
+      <type>PIPELINE</type>
+      <attributes/>
+      <add_date>N</add_date>
+      <add_time>N</add_time>
+      <clear_files>N</clear_files>
+      <clear_rows>N</clear_rows>
       <create_parent_folder>N</create_parent_folder>
-      <run_configuration>local</run_configuration>
+      <exec_per_row>N</exec_per_row>
+      
<filename>${PROJECT_HOME}/0009-database-join-cache-large-enough.hpl</filename>
+      <logext/>
+      <logfile/>
+      <loglevel>Basic</loglevel>
       <parameters>
         <pass_all_parameters>Y</pass_all_parameters>
       </parameters>
+      <params_from_previous>N</params_from_previous>
+      <run_configuration>transactional</run_configuration>
+      <set_append_logfile>N</set_append_logfile>
+      <set_logfile>N</set_logfile>
+      <wait_until_finished>Y</wait_until_finished>
       <parallel>N</parallel>
-      <xloc>864</xloc>
+      <xloc>2320</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>Check input rows limited cache size very big</name>
+      <description/>
+      <type>EVAL</type>
+      <attributes/>
+      <script>var inputz = previous_result.getNrLinesInput();
+var expectedInputs = 10;
+var ok=true;
+log.logBasic("Expected never to evict cache due to it's big dimension, so like 
the unlimited results");
+if(inputz == expectedInputs){
+       ok = true;
+       log.logBasic("Got " + inputz + " as expected");
+       
+} else {
+       ok = false;
+       log.logError("Expected " + expectedInputs + ", actual: " + inputz);
+}
+
+ok;</script>
+      <parallel>N</parallel>
+      <xloc>2624</xloc>
       <yloc>48</yloc>
       <attributes_hac/>
     </action>
@@ -181,6 +323,48 @@ limitations under the License.
       <evaluation>Y</evaluation>
       <unconditional>N</unconditional>
     </hop>
+    <hop>
+      <from>0009-database-join-parameter</from>
+      <to>0009-database-join-cache-unlimited-size</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
+    <hop>
+      <from>0009-database-join-cache-unlimited-size</from>
+      <to>Check input rows unlimited cache size</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
+    <hop>
+      <from>Check input rows unlimited cache size</from>
+      <to>0009-database-join-cache-undersized.hpl</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
+    <hop>
+      <from>0009-database-join-cache-undersized.hpl</from>
+      <to>Check input rows limited size</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
+    <hop>
+      <from>Check input rows limited size</from>
+      <to>0009-database-join-cache-large-enough</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
+    <hop>
+      <from>0009-database-join-cache-large-enough</from>
+      <to>Check input rows limited cache size very big</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>N</unconditional>
+    </hop>
   </hops>
   <notepads>
   </notepads>
diff --git a/integration-tests/database/scripts/script2.sql 
b/integration-tests/database/scripts/script2.sql
index 214c3a1fde..85e77efeb4 100644
--- a/integration-tests/database/scripts/script2.sql
+++ b/integration-tests/database/scripts/script2.sql
@@ -31,3 +31,23 @@ VALUES ('10', 'aa'),
        ('40', 'dd'),
        ('50', 'ee')
 ;
+
+DROP TABLE IF EXISTS public.foo;
+
+CREATE TABLE public.foo
+(
+    id          integer,
+    name        varchar(255),
+    description text
+);
+
+INSERT INTO foo (id, name, description) VALUES (1, 'Alice', 'Dont judge each 
day by the harvest you reap but by the seeds that you plant. -Robert Louis 
Stevenson');
+INSERT INTO foo (id, name, description) VALUES (2, 'Charlie', 'The way to get 
started is to quit talking and begin doing. -Walt Disney');
+INSERT INTO foo (id, name, description) VALUES (3, 'Charlie', 'Life is what 
happens when youre busy making other plans. -John Lennon');
+INSERT INTO foo (id, name, description) VALUES (4, 'Alice', 'The way to get 
started is to quit talking and begin doing. -Walt Disney');
+INSERT INTO foo (id, name, description) VALUES (5, 'Charlie', 'Your time is 
limited, dont waste it living someone elses life. -Steve Jobs');
+INSERT INTO foo (id, name, description) VALUES (6, 'Bob', 'Spread love 
everywhere you go. -Mother Teresa');
+INSERT INTO foo (id, name, description) VALUES (7, 'Alice', 'Life is what 
happens when youre busy making other plans. -John Lennon');
+INSERT INTO foo (id, name, description) VALUES (8, 'Bob', 'If life were 
predictable it would cease to be life, and be without flavor. -Eleanor 
Roosevelt');
+INSERT INTO foo (id, name, description) VALUES (9, 'Bob', 'If you look at what 
you have in life, youll always have more. -Oprah Winfrey');
+INSERT INTO foo (id, name, description) VALUES (10, 'Alice', 'Your time is 
limited, dont waste it living someone elses life. -Steve Jobs');
diff --git 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoin.java
 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoin.java
index 504c7a297e..156ecc880f 100644
--- 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoin.java
+++ 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoin.java
@@ -18,6 +18,8 @@
 package org.apache.hop.pipeline.transforms.databasejoin;
 
 import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.locks.ReentrantLock;
 import org.apache.hop.core.database.Database;
 import org.apache.hop.core.database.DatabaseMeta;
@@ -33,6 +35,7 @@ import org.apache.hop.pipeline.Pipeline;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.BaseTransform;
 import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.pipeline.transforms.databasejoin.cache.DatabaseCache;
 
 /**
  * Use values from input streams to joins with values in a database. Freehand 
SQL can be used to do
@@ -101,38 +104,28 @@ public class DatabaseJoin extends 
BaseTransform<DatabaseJoinMeta, DatabaseJoinDa
         lookupRowData[i] = rowData[data.keynrs[i]];
       }
 
-      // Set the values on the prepared statement (for faster exec.)
-      rs = data.db.openQuery(data.pstmt, data.lookupRowMeta, lookupRowData);
+      List<Object[]> adds = getFromCacheOrFetch(lookupRowData);
 
-      // Get a row from the database...
-      //
-      Object[] add = data.db.getRow(rs);
       IRowMeta addMeta = data.db.getReturnRowMeta();
 
-      incrementLinesInput();
-
       int counter = 0;
-      while (add != null && (meta.getRowLimit() == 0 || counter < 
meta.getRowLimit())) {
-        counter++;
-
-        Object[] newRow = RowDataUtil.resizeArray(rowData, 
data.outputRowMeta.size());
-        int newIndex = rowMeta.size();
-        for (int i = 0; i < addMeta.size(); i++) {
-          newRow[newIndex++] = add[i];
-        }
-        // we have to clone, otherwise we only get the last new value
-        putRow(data.outputRowMeta, data.outputRowMeta.cloneRow(newRow));
-
-        if (log.isRowLevel()) {
-          logRowlevel(
-              BaseMessages.getString(PKG, "DatabaseJoin.Log.PutoutRow")
-                  + data.outputRowMeta.getString(newRow));
-        }
+      for (Object[] add : adds) {
+        if (add != null && (meta.getRowLimit() == 0 || counter < 
meta.getRowLimit())) {
+          counter++;
+
+          Object[] newRow = RowDataUtil.resizeArray(rowData, 
data.outputRowMeta.size());
+          int newIndex = rowMeta.size();
+          for (int i = 0; i < addMeta.size(); i++) {
+            newRow[newIndex++] = add[i];
+          }
+          // we have to clone, otherwise we only get the last new value
+          putRow(data.outputRowMeta, data.outputRowMeta.cloneRow(newRow));
 
-        // Get a new row
-        if (meta.getRowLimit() == 0 || counter < meta.getRowLimit()) {
-          add = data.db.getRow(rs);
-          incrementLinesInput();
+          if (log.isRowLevel()) {
+            logRowlevel(
+                BaseMessages.getString(PKG, "DatabaseJoin.Log.PutoutRow")
+                    + data.outputRowMeta.getString(newRow));
+          }
         }
       }
 
@@ -151,12 +144,39 @@ public class DatabaseJoin extends 
BaseTransform<DatabaseJoinMeta, DatabaseJoinDa
         putRow(data.outputRowMeta, newRow);
       }
 
-      data.db.closeQuery(rs);
     } finally {
       dbLock.unlock();
     }
   }
 
+  private List<Object[]> getFromCacheOrFetch(Object[] lookupRowData) throws 
HopDatabaseException {
+    if (meta.isCached()) {
+      List<Object[]> adds = data.cache.getRowsFromCache(data.lookupRowMeta, 
lookupRowData);
+      if (adds != null) {
+        return adds;
+      } else {
+        List<Object[]> fromDatabase = fetchFromDatabase(lookupRowData);
+        data.cache.putRowsIntoCache(data.lookupRowMeta, lookupRowData, 
fromDatabase);
+        return fromDatabase;
+      }
+    }
+    return fetchFromDatabase(lookupRowData);
+  }
+
+  private List<Object[]> fetchFromDatabase(Object[] lookupRowData) throws 
HopDatabaseException {
+    List<Object[]> result = new ArrayList<>();
+
+    ResultSet rs = data.db.openQuery(data.pstmt, data.lookupRowMeta, 
lookupRowData);
+    Object[] add = data.db.getRow(rs);
+    while (add != null) {
+      result.add(add);
+      incrementLinesInput();
+      add = data.db.getRow(rs);
+    }
+    data.db.closeQuery(rs);
+    return result;
+  }
+
   @Override
   public boolean processRow() throws HopException {
 
@@ -267,6 +287,10 @@ public class DatabaseJoin extends 
BaseTransform<DatabaseJoinMeta, DatabaseJoinDa
           }
           data.db.setQueryLimit(meta.getRowLimit());
 
+          if (meta.isCached()) {
+            data.cache = new DatabaseCache(meta.getCacheSize());
+          }
+
           return true;
         } catch (HopException e) {
           logError(
@@ -301,6 +325,7 @@ public class DatabaseJoin extends 
BaseTransform<DatabaseJoinMeta, DatabaseJoinDa
         data.db.disconnect();
         data.db = null;
       }
+      data.cache = null;
       dbLock.unlock();
     }
   }
diff --git 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinData.java
 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinData.java
index 47cd91374b..7cfd5ee352 100644
--- 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinData.java
+++ 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinData.java
@@ -22,10 +22,12 @@ import org.apache.hop.core.database.Database;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.pipeline.transform.BaseTransformData;
 import org.apache.hop.pipeline.transform.ITransformData;
+import org.apache.hop.pipeline.transforms.databasejoin.cache.DatabaseCache;
 
 public class DatabaseJoinData extends BaseTransformData implements 
ITransformData {
   public Database db;
   public PreparedStatement pstmt;
+  public DatabaseCache cache;
 
   IRowMeta outputRowMeta;
   IRowMeta lookupRowMeta;
@@ -39,5 +41,6 @@ public class DatabaseJoinData extends BaseTransformData 
implements ITransformDat
 
     db = null;
     notfound = null;
+    cache = null;
   }
 }
diff --git 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java
 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java
index 54873df9b2..9d79759360 100644
--- 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java
+++ 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java
@@ -84,6 +84,11 @@ public class DatabaseJoinDialog extends BaseTransformDialog 
implements ITransfor
 
   private final List<String> inputFields = new ArrayList<>();
 
+  private Button wCache;
+
+  private Label wlCacheSize;
+  private Text wCacheSize;
+
   public DatabaseJoinDialog(
       Shell parent, IVariables variables, Object in, PipelineMeta tr, String 
sname) {
     super(parent, variables, (BaseTransformMeta) in, tr, sname);
@@ -133,13 +138,57 @@ public class DatabaseJoinDialog extends 
BaseTransformDialog implements ITransfor
     // Connection line
     wConnection = addConnectionLine(shell, wTransformName, 
input.getConnection(), lsMod);
 
+    // ICache?
+    Label wlCache = new Label(shell, SWT.RIGHT);
+    wlCache.setText(BaseMessages.getString(PKG, 
"DatabaseJoinDialog.Cache.Label"));
+    PropsUi.setLook(wlCache);
+    FormData fdlCache = new FormData();
+    fdlCache.left = new FormAttachment(0, 0);
+    fdlCache.right = new FormAttachment(middle, -margin);
+    fdlCache.top = new FormAttachment(wConnection, margin);
+    wlCache.setLayoutData(fdlCache);
+    wCache = new Button(shell, SWT.CHECK);
+    PropsUi.setLook(wCache);
+    FormData fdCache = new FormData();
+    fdCache.left = new FormAttachment(middle, 0);
+    fdCache.top = new FormAttachment(wlCache, 0, SWT.CENTER);
+    wCache.setLayoutData(fdCache);
+    wCache.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent e) {
+            input.setChanged();
+            enableFields();
+          }
+        });
+
+    // ICache size line
+    wlCacheSize = new Label(shell, SWT.RIGHT);
+    wlCacheSize.setText(BaseMessages.getString(PKG, 
"DatabaseJoinDialog.CacheSize.Label"));
+    PropsUi.setLook(wlCacheSize);
+    wlCacheSize.setEnabled(input.isCached());
+    FormData fdlCacheSize = new FormData();
+    fdlCacheSize.left = new FormAttachment(0, 0);
+    fdlCacheSize.right = new FormAttachment(middle, -margin);
+    fdlCacheSize.top = new FormAttachment(wCache, margin);
+    wlCacheSize.setLayoutData(fdlCacheSize);
+    wCacheSize = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    PropsUi.setLook(wCacheSize);
+    wCacheSize.setEnabled(input.isCached());
+    wCacheSize.addModifyListener(lsMod);
+    FormData fdCacheSize = new FormData();
+    fdCacheSize.left = new FormAttachment(middle, 0);
+    fdCacheSize.right = new FormAttachment(100, 0);
+    fdCacheSize.top = new FormAttachment(wCache, margin);
+    wCacheSize.setLayoutData(fdCacheSize);
+
     // SQL editor...
     Label wlSql = new Label(shell, SWT.NONE);
     wlSql.setText(BaseMessages.getString(PKG, "DatabaseJoinDialog.SQL.Label"));
     PropsUi.setLook(wlSql);
     FormData fdlSql = new FormData();
     fdlSql.left = new FormAttachment(0, 0);
-    fdlSql.top = new FormAttachment(wConnection, margin * 2);
+    fdlSql.top = new FormAttachment(wlCache, margin * 2);
     wlSql.setLayoutData(fdlSql);
 
     wSql =
@@ -360,6 +409,11 @@ public class DatabaseJoinDialog extends 
BaseTransformDialog implements ITransfor
     return transformName;
   }
 
+  private void enableFields() {
+    wCacheSize.setEnabled(wCache.getSelection());
+    wlCacheSize.setEnabled(wCache.getSelection());
+  }
+
   protected void setComboBoxes() {
     // Something was changed in the row.
     //
@@ -380,6 +434,10 @@ public class DatabaseJoinDialog extends 
BaseTransformDialog implements ITransfor
     logDebug(BaseMessages.getString(PKG, 
"DatabaseJoinDialog.Log.GettingKeyInfo"));
 
     wConnection.setText(Const.NVL(input.getConnection(), ""));
+
+    wCache.setSelection(input.isCached());
+    wCacheSize.setText("" + input.getCacheSize());
+
     wSql.setText(Const.NVL(input.getSql(), ""));
     wLimit.setText("" + input.getRowLimit());
     wOuter.setSelection(input.isOuterJoin());
@@ -398,6 +456,8 @@ public class DatabaseJoinDialog extends BaseTransformDialog 
implements ITransfor
     wParam.setRowNums();
     wParam.optWidth(true);
 
+    enableFields();
+
     wTransformName.selectAll();
     wTransformName.setFocus();
   }
@@ -416,6 +476,8 @@ public class DatabaseJoinDialog extends BaseTransformDialog 
implements ITransfor
     int nrparam = wParam.nrNonEmpty();
 
     input.setConnection(wConnection.getText());
+    input.setCached(wCache.getSelection());
+    input.setCacheSize(Const.toInt(wCacheSize.getText(), 0));
     input.setRowLimit(Const.toInt(wLimit.getText(), 0));
     input.setSql(wSql.getText());
     input.setOuterJoin(wOuter.getSelection());
diff --git 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
index 793521a915..e3312f8d98 100644
--- 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
+++ 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinMeta.java
@@ -60,6 +60,15 @@ public class DatabaseJoinMeta extends 
BaseTransformMeta<DatabaseJoin, DatabaseJo
       injectionKeyDescription = "DatabaseJoinMeta.Injection.Connection")
   private String connection;
 
+  @HopMetadataProperty(key = "cache", injectionKeyDescription = 
"DatabaseJoinMeta.Injection.Cache")
+  private boolean cached;
+
+  /** Limit the cache size to this! */
+  @HopMetadataProperty(
+      key = "cache_size",
+      injectionKeyDescription = "DatabaseJoinMeta.Injection.CacheSize")
+  private int cacheSize;
+
   /** SQL Statement */
   @HopMetadataProperty(key = "sql", injectionKeyDescription = 
"DatabaseJoinMeta.Injection.SQL")
   private String sql;
@@ -108,6 +117,8 @@ public class DatabaseJoinMeta extends 
BaseTransformMeta<DatabaseJoin, DatabaseJo
     for (ParameterField field : clone.parameters) {
       parameters.add(new ParameterField(field));
     }
+    this.cached = clone.cached;
+    this.cacheSize = clone.cacheSize;
   }
 
   public String getConnection() {
@@ -118,6 +129,38 @@ public class DatabaseJoinMeta extends 
BaseTransformMeta<DatabaseJoin, DatabaseJo
     this.connection = connection;
   }
 
+  /**
+   * Gets cached
+   *
+   * @return value of cached
+   */
+  public boolean isCached() {
+    return cached;
+  }
+
+  /**
+   * @param cached The cached to set
+   */
+  public void setCached(boolean cached) {
+    this.cached = cached;
+  }
+
+  /**
+   * Gets cacheSize
+   *
+   * @return value of cacheSize
+   */
+  public int getCacheSize() {
+    return cacheSize;
+  }
+
+  /**
+   * @param cacheSize The cacheSize to set
+   */
+  public void setCacheSize(int cacheSize) {
+    this.cacheSize = cacheSize;
+  }
+
   /**
    * @return Returns the outerJoin.
    */
diff --git 
a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/cache/DatabaseCache.java
 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/cache/DatabaseCache.java
new file mode 100644
index 0000000000..ef7a375231
--- /dev/null
+++ 
b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/cache/DatabaseCache.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.pipeline.transforms.databasejoin.cache;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.hop.core.RowMetaAndData;
+import org.apache.hop.core.row.IRowMeta;
+
+public class DatabaseCache {
+
+  private Map<RowMetaAndData, List<Object[]>> cache;
+
+  public DatabaseCache(int maxSize) {
+    cache = new EvictableCacheMap(maxSize);
+  }
+
+  public List<Object[]> getRowsFromCache(IRowMeta lookupMeta, Object[] 
lookupRow) {
+    return getRowsFromCache(new RowMetaAndData(lookupMeta, lookupRow));
+  }
+
+  public List<Object[]> getRowsFromCache(RowMetaAndData key) {
+    return cache.getOrDefault(key, null);
+  }
+
+  public void putRowsIntoCache(RowMetaAndData key, List<Object[]> values) {
+    cache.put(key, values);
+  }
+
+  public void putRowsIntoCache(IRowMeta lookupMeta, Object[] lookupRow, 
List<Object[]> values) {
+    putRowsIntoCache(new RowMetaAndData(lookupMeta, lookupRow), values);
+  }
+
+  private static class EvictableCacheMap extends LinkedHashMap<RowMetaAndData, 
List<Object[]>> {
+
+    private final int maxSize;
+
+    public EvictableCacheMap(int maxSize) {
+      super();
+      this.maxSize = maxSize;
+    }
+
+    @Override
+    protected boolean removeEldestEntry(Map.Entry<RowMetaAndData, 
List<Object[]>> eldest) {
+      return maxSize > 0
+          && size() > maxSize; // do not remove entries if maxSize is 0 
(inherit from LinkedHashMap)
+    }
+  }
+
+  public boolean isEmpty() {
+    return cache.isEmpty();
+  }
+}
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_de_DE.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_de_DE.properties
index 51d35bbcfa..4224651cd5 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_de_DE.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_de_DE.properties
@@ -20,39 +20,39 @@
 DatabaseJoin.Name=Datenbank-Join
 DatabaseJoin.Description=F\u00FChrt eine Datenbankabfrage mit Parametern aus 
vorherigen Transforms aus
 DatabaseJoinDialog.Shell.Title=Datenbank-Join
-DatabaseJoinDialog.TransformName.Label=Transform Name 
-DatabaseJoinDialog.SQL.Label=SQL 
+DatabaseJoinDialog.TransformName.Label=Transform Name
+DatabaseJoinDialog.SQL.Label=SQL
 DatabaseJoinDialog.Limit.Label=Zeilenanzahl der Ausgabe ( 0=alle )
 DatabaseJoinDialog.Outerjoin.Label=Outer Join?
-DatabaseJoinDialog.GetFields.Button=\ &Lade Felder 
-DatabaseJoinDialog.Param.Label=Die zu benutzenden Parameter: 
+DatabaseJoinDialog.GetFields.Button=\ &Lade Felder
+DatabaseJoinDialog.Param.Label=Die zu benutzenden Parameter:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Parameter Feldname
 DatabaseJoinDialog.ColumnInfo.ParameterType=Parametertyp
 DatabaseJoinDialog.Log.GettingKeyInfo=Lade Schl\u00FCsselinformationen...
-DatabaseJoinDialog.Log.ParametersFound=Gefunden 
+DatabaseJoinDialog.Log.ParametersFound=Gefunden
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Bitte w\u00E4hlen Sie eine 
g\u00FCltige Verbindung\!
 DatabaseJoinDialog.InvalidConnection.DialogTitle=FEHLER
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Laden der Felder ist 
fehlgeschlagen
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Felder von einem vorherigen 
Transform konnten nicht geladen werden
-DatabaseJoin.Log.PutoutRow=Zeile ausgeben: 
-DatabaseJoin.Log.LineNumber=Zeilennr 
-DatabaseJoin.Log.ErrorInTransformRunning=Der Schritt kann wegen einem Fehler 
nicht fortfahren: 
+DatabaseJoin.Log.PutoutRow=Zeile ausgeben:
+DatabaseJoin.Log.LineNumber=Zeilennr
+DatabaseJoin.Log.ErrorInTransformRunning=Der Schritt kann wegen einem Fehler 
nicht fortfahren:
 DatabaseJoin.Log.ConnectedToDB=Verbunden zur Datenbank...
-DatabaseJoin.Log.DatabaseError=Ein Datenbankfehler ist aufgetreten und hat 
alles abgebrochen: 
+DatabaseJoin.Log.DatabaseError=Ein Datenbankfehler ist aufgetreten und hat 
alles abgebrochen:
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Konnte die Felder der 
Abfrage nicht ermitteln:
 DatabaseJoinMeta.CheckResult.QueryOK=Die Abfrage wurde festgelegt und 
funktioniert.
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=Die Anzahl 
der Parameter und die Anzahl der Fragezeichen ist unterschiedlich.
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tDie 
Anzahl der Fragezeichen = 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tDie 
Anzahl der Parameter    = 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tDie 
Anzahl der Fragezeichen =
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tDie 
Anzahl der Parameter    =
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=Die Anzahl der Parameter ist 
korrekt. (
 DatabaseJoinMeta.CheckResult.MissingFields=Fehlende Felder, die nicht im Input 
von vorherigen Transforms gefunden wurden:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Alle Felder wurden im Input 
Datenstrom gefunden.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Konnte keine Felder von 
vorherigen Transforms lesen.
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Ein Fehler ist aufgetreten: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Ein Fehler ist aufgetreten:
 DatabaseJoinMeta.CheckResult.InvalidConnection=Bitte w\u00E4hlen oder 
erstellen Sie eine Verbindung\!
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Schritt empf\u00E4ngt Informationen 
von anderen Transforms.
 DatabaseJoinMeta.CheckResult.NoInputReceived=Kein Input empfangen von anderen 
Schritten\!
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ein Datenbankfehler ist 
aufgetreten: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ein Datenbankfehler ist aufgetreten:
 DatabaseJoinMeta.DatabaseImpact.Title=Liest von einer oder mehreren 
Datenbanktabellen per SQL-Anweisung
 DatabaseJoinDialog.useVarsjoin.Label=Variablen ersetzen
 DatabaseJoinDialog.useVarsjoin.Tooltip=Sollen Variablen im SQL Skript ersetzt 
werden ?
@@ -60,7 +60,7 @@ DatabaseJoin.Exception.FieldNotFound=Feld [{0}] wird 
ben\u00F6tigt und konnte ni
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Fehler bei der Ermittlung von 
Feldern
 DatabaseJoin.Log.SQLStatement=Bereite SQL Statement vor : {0}
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Konnte Datenbankabfrage nicht 
verifizieren, siehe Log !
-DatabaseJoin.Log.CheckingRow=Pr\u00FCfe Zeile : 
+DatabaseJoin.Log.CheckingRow=Pr\u00FCfe Zeile :
 DatabaseJoin.Init.ConnectionMissing=Datenbankverbindung fehlt f\u00FCr 
Transform [{0}] !
 DatabaseJoinMeta.Injection.Connection=Verbindung
 DatabaseJoinMeta.Injection.SQL=SQL
@@ -70,8 +70,12 @@ DatabaseJoinMeta.Injection.Field=Feld
 DatabaseJoinMeta.Injection.Parameters=Parameter Feld
 DatabaseJoinMeta.Injection.Parameter.Name=Feldname
 DatabaseJoinMeta.Injection.Parameter.Type=Feldtyp
-DatabaseJoinMeta.CheckResult.DatabaseMetaError=Konnte keine Metadaten-Referenz 
f\u00FCr DB Verbindung finden: "{0}" 
+DatabaseJoinMeta.CheckResult.DatabaseMetaError=Konnte keine Metadaten-Referenz 
f\u00FCr DB Verbindung finden: "{0}"
 DatabaseJoinMeta.keyword=database,db,join,datenbank
 DatabaseJoinMeta.Injection.ReplaceVariables=Variablen im SQL Skript ersetzen ?
 DatabaseJoinDialog.Position.Label=Zeile {0} Spalte {1}
 DatabaseJoinDialog.Outerjoin.Tooltip=Gib mindestens die EIngabezeile 
zur\u00FCck und f\u00FCge NULL Werte f\u00FCr die Suchfelder hinzu
+DatabaseJoinDialog.Cache.Label=Cache aktivieren?
+DatabaseJoinDialog.CacheSize.Label=Cache Gr\u00F6\u00DFe in Zeilen (0\=alle)
+DatabaseJoinDialog.Injection.Cache=Suchdaten zwischenspeichern (cache)?
+DatabaseJoinDialog.Injection.CacheSize=Puffergr\u00F6\u00DFe (cache) in Zeilen 
(0\=alle)
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_en_US.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_en_US.properties
index e9b30a6dc4..0b4f702df7 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_en_US.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_en_US.properties
@@ -17,50 +17,52 @@
 
 DatabaseJoin.Name=Database join
 DatabaseJoin.Description=Execute a database query using stream values as 
parameters
-DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\:
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Please select a valid 
connection\!
 DatabaseJoinDialog.useVarsjoin.Label=Replace variables
 DatabaseJoinDialog.useVarsjoin.Tooltip=Replace variables in SQL script
 DatabaseJoinDialog.Limit.Label=Number of rows to return
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\: 
-DatabaseJoin.Log.DatabaseError=A database error occurred, stopping 
everything\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\:
+DatabaseJoin.Log.DatabaseError=A database error occurred, stopping everything\:
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Get fields failed
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Unable to get fields from 
previous transforms because of an error
 DatabaseJoin.Exception.FieldNotFound=Field [{0}] is required and couldn''t be 
found\!
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Error obtaining fields for 
this transform
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \=
 DatabaseJoinDialog.Log.GettingKeyInfo=getting key info...
-DatabaseJoin.Log.PutoutRow=Put out row\: 
+DatabaseJoin.Log.PutoutRow=Put out row\:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=All fields found in the input 
stream.
 DatabaseJoinMeta.DatabaseImpact.Title=read from one or more database tables 
via SQL statement
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Transform is receiving info from 
other transforms.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Couldn''t read fields from 
the previous transform.
-DatabaseJoin.Log.LineNumber=linenr 
+DatabaseJoin.Log.LineNumber=linenr
 DatabaseJoinMeta.CheckResult.InvalidConnection=Please select or create a 
connection\!
 DatabaseJoinDialog.Position.Label=Line {0} Column {1}
 DatabaseJoinMeta.CheckResult.MissingFields=Missing fields, not found in input 
from previous transforms\:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Parameter fieldname
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Unable to determine 
the fields of query\:
 DatabaseJoinDialog.Shell.Title=Database join
-DatabaseJoinDialog.SQL.Label=SQL 
-DatabaseJoinDialog.Log.ParametersFound=Found 
+DatabaseJoinDialog.SQL.Label=SQL
+DatabaseJoinDialog.Log.ParametersFound=Found
 DatabaseJoin.Log.ConnectedToDB=Connected to database...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERROR
-DatabaseJoinDialog.Param.Label=The parameters to use\: 
-DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\: 
+DatabaseJoinDialog.Param.Label=The parameters to use\:
+DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\:
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=The number 
of parameters and the number of question marks is different.
 DatabaseJoinMeta.CheckResult.QueryOK=The query is specified and working 
correctly.
 DatabaseJoinDialog.Outerjoin.Tooltip=Return al least the input row and add 
NULLs for the lookup values
 DatabaseJoinMeta.CheckResult.NoInputReceived=No input received from other 
transforms\!
 DatabaseJoinDialog.Outerjoin.Label=Outer join?
 DatabaseJoinDialog.ColumnInfo.ParameterType=Parameter Type
-DatabaseJoinDialog.TransformName.Label=Transform name 
+DatabaseJoinDialog.TransformName.Label=Transform name
 DatabaseJoin.Log.SQLStatement=Prepare SQL statement \: {0}
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=The number of parameters is 
correct. (
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Couldn''t verify the database 
query\: check the log for more info\!
-DatabaseJoinDialog.GetFields.Button=\ &Get Fields 
-DatabaseJoin.Log.CheckingRow=Checking row\: 
+DatabaseJoinDialog.GetFields.Button=\ &Get Fields
+DatabaseJoinDialog.Cache.Label=Enable cache?
+DatabaseJoinDialog.CacheSize.Label=Cache size in rows (0\: cache everything)
+DatabaseJoin.Log.CheckingRow=Checking row\:
 DatabaseJoin.Init.ConnectionMissing=Database connection is missing for 
transform [{0}]\!
 DatabaseJoinMeta.Injection.Connection=Connection
 DatabaseJoinMeta.Injection.SQL=SQL
@@ -71,5 +73,7 @@ DatabaseJoinMeta.Injection.Parameters=The parameter fields to 
use
 DatabaseJoinMeta.Injection.Parameter.Name=Field name
 DatabaseJoinMeta.Injection.Parameter.Type=Field type
 DatabaseJoinMeta.Injection.ReplaceVariables=Replace variables in SQL script ? 
(Y/N)
-DatabaseJoinMeta.CheckResult.DatabaseMetaError=Unable to get a reference to 
databaseMeta for connection: ''{0}'' 
-DatabaseJoinMeta.keyword=database,db,join
\ No newline at end of file
+DatabaseJoinMeta.CheckResult.DatabaseMetaError=Unable to get a reference to 
databaseMeta for connection: ''{0}''
+DatabaseJoinMeta.keyword=database,db,join
+DatabaseJoinMeta.Injection.Cache=Enable cache ? (Y/N)
+DatabaseJoinMeta.Injection.CacheSize=Cache size in rows
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_AR.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_AR.properties
index 006c973da8..d3d7485b51 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_AR.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_AR.properties
@@ -24,42 +24,48 @@ 
DatabaseJoinDialog.InvalidConnection.DialogMessage=\u00A1Por favor seleccione un
 DatabaseJoinDialog.useVarsjoin.Label=Reemplazar variables
 DatabaseJoinDialog.useVarsjoin.Tooltip=Reemplazar variables en script SQL
 DatabaseJoinDialog.Limit.Label=N\u00FAmero de filas a devolver
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Se ha producido un error de base de 
datos\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Se ha producido un error de base de 
datos\:
 DatabaseJoin.Log.DatabaseError=Se ha producido un error de base de datos, 
deteniendo todo\:
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=No se han podido obtener los 
campos
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=No se han podido obtener los 
campos de pasos anteriores debido a un error
 DatabaseJoin.Exception.FieldNotFound=\u00A1El campo [{0}] es requerido pero no 
se encuentra\!
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Error obteniendo campos para 
este paso
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tN\u00FAmero
 de par\u00E1metros    \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tN\u00FAmero
 de s\u00EDmbolos de interrogaci\u00F3n \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tN\u00FAmero
 de par\u00E1metros    \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tN\u00FAmero
 de s\u00EDmbolos de interrogaci\u00F3n \=
 DatabaseJoinDialog.Log.GettingKeyInfo=obteniendo informaci\u00F3n de clave...
 DatabaseJoin.Log.PutoutRow=Fila de salida\:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Se han encontrado todos los campos 
en el flujo de entrada.
 DatabaseJoinMeta.DatabaseImpact.Title=leer de tablas de la base de datos via 
sentencia SQL
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Este paso recibe informaci\u00F3n 
de otros pasos.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=No se han podido leer campos 
de los pasos anteriores.
-DatabaseJoin.Log.LineNumber=N\u00FAmero de l\u00EDnea 
+DatabaseJoin.Log.LineNumber=N\u00FAmero de l\u00EDnea
 DatabaseJoinMeta.CheckResult.InvalidConnection=\u00A1Por favor seleccione o 
cree una conexi\u00F3n\!
 DatabaseJoinDialog.Position.Label=L\u00EDnea {0} Columna {1}
 DatabaseJoinMeta.CheckResult.MissingFields=No se han encontrado los siguientes 
campos en la entrada de pasos anteriores\:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Nombre del campo 
par\u00E1metro
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=No se han podido 
determinar los campos de la consulta\:
 DatabaseJoinDialog.Shell.Title=Join de base de datos
-DatabaseJoinDialog.SQL.Label=SQL 
-DatabaseJoinDialog.Log.ParametersFound=Encontrado 
+DatabaseJoinDialog.SQL.Label=SQL
+DatabaseJoinDialog.Log.ParametersFound=Encontrado
 DatabaseJoin.Log.ConnectedToDB=Conectado a la base de datos...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERROR
-DatabaseJoinDialog.Param.Label=Par\u00E1metros a utilizar\: 
-DatabaseJoin.Log.ErrorInTransformRunning=Este paso no puede continuar debido a 
un error\: 
+DatabaseJoinDialog.Param.Label=Par\u00E1metros a utilizar\:
+DatabaseJoin.Log.ErrorInTransformRunning=Este paso no puede continuar debido a 
un error\:
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=El 
n\u00FAmero de par\u00E1metros y de s\u00EDmbolos de interrogaci\u00F3n no 
coinciden.
 DatabaseJoinMeta.CheckResult.QueryOK=Se ha especificado la consulta, y 
funciona correctamente.
 DatabaseJoinDialog.Outerjoin.Tooltip=Devolver al menos la fila de entrada y 
a\u00F1adir valores nulos para los valores de b\u00FAsqueda
 DatabaseJoinMeta.CheckResult.NoInputReceived=No se recibe ninguna entrada de 
otros pasos.
 DatabaseJoinDialog.Outerjoin.Label=\u00BFOuter join?
-DatabaseJoinDialog.TransformName.Label=Nombre de paso 
+DatabaseJoinDialog.TransformName.Label=Nombre de paso
 DatabaseJoinDialog.ColumnInfo.ParameterType=Tipo de par\u00E1metro
 DatabaseJoin.Log.SQLStatement=Preparar sentencia SQL\: {0}
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=El n\u00FAmero de 
par\u00E1metros es correcto. (
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=No se ha podido verificar la 
consulta\: revise el registro en busca de m\u00E1s informaci\u00F3n\!
-DatabaseJoinDialog.GetFields.Button=\ &Obtener campos 
-DatabaseJoin.Log.CheckingRow=Comprobando fila\: 
+DatabaseJoinDialog.GetFields.Button=\ &Obtener campos
+DatabaseJoin.Log.CheckingRow=Comprobando fila\:
+DatabaseJoinDialog.Cache.Label=Cache aktivieren?
+DatabaseJoinDialog.CacheSize.Label=Gr\u00F6\u00DFe des Cache in Zeilen 
(0=alles cachen)
+DatabaseJoinDialog.Injection.Cache=Suchdaten zwischenspeichern (cache)?
+DatabaseJoinDialog.Injection.CacheSize=Puffergr\u00F6\u00DFe (cache)
+DatabaseJoinDialog.Injection.CacheLoadAll=Alle Zeilen in den Puffer laden 
(cache)?
+
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_ES.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_ES.properties
index 3f5ed848c9..2667f3bde6 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_ES.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_es_ES.properties
@@ -20,26 +20,26 @@
 DatabaseJoin.Name=Consulta base de datos
 DatabaseJoin.Description=Ejecutar una consulta de base de datos utilizando 
valores de flujos como par\u00E1meteros
 DatabaseJoinDialog.Shell.Title=Consulta a base de datos
-DatabaseJoinDialog.TransformName.Label=Nombre de paso 
-DatabaseJoinDialog.SQL.Label=SQL 
+DatabaseJoinDialog.TransformName.Label=Nombre de paso
+DatabaseJoinDialog.SQL.Label=SQL
 DatabaseJoinDialog.Limit.Label=N\u00FAmero de filas a devolver
 DatabaseJoinDialog.Outerjoin.Label=¿Outer join?
 DatabaseJoinDialog.Outerjoin.Tooltip=Devolver al menos la fila de entrada y 
añadir Valores Nulos para los valores de búsqueda
-DatabaseJoinDialog.GetFields.Button=\ &Obtener campos 
-DatabaseJoinDialog.Param.Label=Los parámetros a utilizar son: 
+DatabaseJoinDialog.GetFields.Button=\ &Obtener campos
+DatabaseJoinDialog.Param.Label=Los parámetros a utilizar son:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Nombre campo parámetro
 DatabaseJoinDialog.ColumnInfo.ParameterType=Tipo parámetro
 DatabaseJoinDialog.Log.GettingKeyInfo=obteniendo informaci\u00F3n de clave...
-DatabaseJoinDialog.Log.ParametersFound=Encontrado 
+DatabaseJoinDialog.Log.ParametersFound=Encontrado
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Por favor selecciona una 
conexi\u00F3n v\u00E1lida\!
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERROR
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=No se ha podido obtener los 
campos
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=No se ha podido obtener los 
campos de pasos anteriores debido a un error
-DatabaseJoin.Log.CheckingRow=Comprobando fila: 
+DatabaseJoin.Log.CheckingRow=Comprobando fila:
 DatabaseJoin.Exception.FieldNotFound=Se necesita el campo [{0}] pero no se 
encuentra!
-DatabaseJoin.Log.PutoutRow=Salida de fila: 
-DatabaseJoin.Log.LineNumber=N\u00FAmero l\u00EDnea 
-DatabaseJoin.Log.ErrorInTransformRunning=Este paso no puede continuar debido a 
un error: 
+DatabaseJoin.Log.PutoutRow=Salida de fila:
+DatabaseJoin.Log.LineNumber=N\u00FAmero l\u00EDnea
+DatabaseJoin.Log.ErrorInTransformRunning=Este paso no puede continuar debido a 
un error:
 DatabaseJoin.Log.ConnectedToDB=Conectado a la base de datos...
 DatabaseJoin.Log.DatabaseError=Se ha producido un error de base de datos, 
parando todo:
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=No se ha podido 
determinar los campos de la consulta:
@@ -47,15 +47,19 @@ DatabaseJoinMeta.Exception.ErrorObtainingFields=Error 
obteniendo campos para est
 DatabaseJoinMeta.CheckResult.QueryOK=La consulta funciona correctamente.
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=No se ha podido verificar la 
consulta: revisa el registro de eventos en busca de más informaci\u00F3n\!
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=El número de 
parámetros e interrogantes no coinciden.
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tN\u00FAmero
 de interrogantes = 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tN\u00FAmero
 de parámetros    = 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tN\u00FAmero
 de interrogantes =
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tN\u00FAmero
 de parámetros    =
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=El número de parámetros es 
correcto. (
 DatabaseJoinMeta.CheckResult.MissingFields=No se ha encontrado los siguientes 
campos en la entrada de pasos anteriores:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Se han encontrado todos los campos 
en el flujo de entrada.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=No se ha podido leer campos 
de los pasos anteriores.
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Se ha producido un error: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Se ha producido un error:
 DatabaseJoinMeta.CheckResult.InvalidConnection=Por favor selecciona o crea una 
conexi\u00F3n\!
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Este paso recibe informaci\u00F3n 
de otros pasos.
 DatabaseJoinMeta.CheckResult.NoInputReceived=No se recibe ninguna entrada de 
otros pasos.
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Se ha producido un error de base de 
datos: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Se ha producido un error de base de 
datos:
 DatabaseJoinMeta.DatabaseImpact.Title=leer de tablas de la base de datos via 
SQL
+DatabaseJoinDialog.Cache.Label= ¿Habilitar cache?
+DatabaseJoinDialog.CacheSize.Label=Tamaño de cache en filas (0\=todas)
+DatabaseJoinDialog.Injection.Cache=Tamaño de cache en filas (0\=todas)
+DatabaseJoinDialog.Injection.CacheSize=0\=todas
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_fr_FR.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_fr_FR.properties
index 4bea838a12..647a3f02a3 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_fr_FR.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_fr_FR.properties
@@ -19,21 +19,21 @@
 #
 DatabaseJoin.Name=Jointure base de donn\u00E9es
 DatabaseJoin.Description=Ex\u00E9cuter une requ\u00EAte SQL en utilisant des 
param\u00E8tres
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Une erreur s''est produite\u00A0: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Une erreur s''est produite\u00A0:
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Veuillez s\u00E9lectionner 
une connexion valide\u202F!
 DatabaseJoinDialog.useVarsjoin.Label=Remplacer variables dans script
 DatabaseJoinDialog.useVarsjoin.Tooltip=Remplacer les variables 
d''environnement dans le script SQL.
 DatabaseJoinDialog.Limit.Label=Nombre de lignes \u00E0 retourner
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Apache Hop a rencontr\u00E9 une 
erreur de base de donn\u00E9es\: 
-DatabaseJoin.Log.DatabaseError=L''ex\u00E9cution va \u00EAtre 
arr\u00EAt\u00E9e suite \u00E0 une erreur\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Apache Hop a rencontr\u00E9 une 
erreur de base de donn\u00E9es\:
+DatabaseJoin.Log.DatabaseError=L''ex\u00E9cution va \u00EAtre 
arr\u00EAt\u00E9e suite \u00E0 une erreur\:
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=R\u00E9cup\u00E9rer champs en 
\u00E9chec
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Impossible de 
r\u00E9cup\u00E9rer les champs depuis les transformations pr\u00E9c\u00E9dentes
 DatabaseJoin.Exception.FieldNotFound=Le champ [{0}] est requis et n''a pas 
\u00E9t\u00E9 trouv\u00E9\!
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Erreur lors de la 
r\u00E9cup\u00E9ration des champs pour cette transformation
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tLe 
nombre de param\u00E8tres     \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tLe 
nombre de points d''interrogation \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tLe 
nombre de param\u00E8tres     \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tLe 
nombre de points d''interrogation \=
 DatabaseJoinDialog.Log.GettingKeyInfo=r\u00E9cup\u00E9ration infos cl\u00E9...
-DatabaseJoin.Log.PutoutRow=Put out row\: 
+DatabaseJoin.Log.PutoutRow=Put out row\:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Tous les champs ont \u00E9t\u00E9 
trouv\u00E9 dans le flux d''entr\u00E9e.
 DatabaseJoinMeta.DatabaseImpact.Title=Interroger une ou plusieurs bases de 
donn\u00E9es via une requ\u00EAte SQL
 DatabaseJoinMeta.CheckResult.ReceivingInfo=La transformation re\u00E7oit des 
informations des autres transformations.
@@ -45,22 +45,26 @@ DatabaseJoinMeta.CheckResult.MissingFields=champs 
manquants, not found in input
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Nom champs param\u00E8tres
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Impossible de 
d\u00E9terminer les champs de la requ\u00EAte\:
 DatabaseJoinDialog.Shell.Title=Jointure base de donn\u00E9es
-DatabaseJoinDialog.SQL.Label=Requ\u00EAte SQL 
-DatabaseJoinDialog.Log.ParametersFound=Trouv\u00E9 
+DatabaseJoinDialog.SQL.Label=Requ\u00EAte SQL
+DatabaseJoinDialog.Log.ParametersFound=Trouv\u00E9
 DatabaseJoin.Log.ConnectedToDB=Connect\u00E9 \u00E0 la base de donn\u00E9es...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERREUR
-DatabaseJoinDialog.Param.Label=Les param\u00E8tres \u00E0 utiliser\: 
-DatabaseJoin.Log.ErrorInTransformRunning=Cette \u00E9tape ne peut \u00EAtre 
ex\u00E9cut\u00E9e\: 
+DatabaseJoinDialog.Param.Label=Les param\u00E8tres \u00E0 utiliser\:
+DatabaseJoin.Log.ErrorInTransformRunning=Cette \u00E9tape ne peut \u00EAtre 
ex\u00E9cut\u00E9e\:
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=Le nombre de 
param\u00E8tres est diff\u00E9rents de celui des point d''interrogation.
 DatabaseJoinMeta.CheckResult.QueryOK=La requ\u00EAte a \u00E9t\u00E9 
sp\u00E9cifi\u00E9e et fonctionne correctement.
 DatabaseJoinDialog.Outerjoin.Tooltip=Returne au moins les lignes en 
entr\u00E9e et ajoute NULLs aux valeurs recherch\u00E9es
 DatabaseJoinMeta.CheckResult.NoInputReceived=Aucun flux d''entr\u00E9e 
re\u00E7u des autres transformations\!
 DatabaseJoinDialog.Outerjoin.Label=Jointure externe
 DatabaseJoinDialog.ColumnInfo.ParameterType=Type Param\u00E8tre
-DatabaseJoinDialog.TransformName.Label=Nom de la transformation 
+DatabaseJoinDialog.TransformName.Label=Nom de la transformation
 DatabaseJoin.Log.SQLStatement=Instruction SQL \u00E0 ex\u00E9cut\u00E9e \: {0}
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=Le nombre de param\u00E8tres 
est correct. (
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Impossible de v\u00E9rifier la 
requ\u00EAte\: veuillez vous reporter au log pour plus de d\u00E9tails\!
-DatabaseJoinDialog.GetFields.Button=\ &R\u00E9cup\u00E9rer les Champs 
-DatabaseJoin.Log.CheckingRow=V\u00E9rification ligne\: 
+DatabaseJoinDialog.GetFields.Button=\ &R\u00E9cup\u00E9rer les Champs
+DatabaseJoin.Log.CheckingRow=V\u00E9rification ligne\:
 DatabaseJoin.Init.ConnectionMissing=La connexion \u00E0 la base de 
donn\u00E9es n''a pas \u00E9t\u00E9 d\u00E9finie ou est introuvable pour la 
transformation [{0}]\!
+DatabaseJoinDialog.Cache.Label=Autoriser la mise en cache
+DatabaseJoinDialog.CacheSize.Label=Nombre de lignes Max dans cache (0\=mise en 
cache de toutes)
+DatabaseJoinDialog.Injection.Cache=Cache
+DatabaseJoinDialog.Injection.CacheSize=Taille du cache
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_it_IT.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_it_IT.properties
index 45c6fbe9d7..94e54a2580 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_it_IT.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_it_IT.properties
@@ -17,49 +17,53 @@
 #
 #
 #
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Errore\: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Errore\:
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Si prega di selezionare una 
connessione valida\!
 DatabaseJoinDialog.useVarsjoin.Label=Sostituisci le variabili
 DatabaseJoinDialog.useVarsjoin.Tooltip=Sostituisce le variabili nello script 
SQL
 DatabaseJoinDialog.Limit.Label=Righe da restituire:
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\: 
-DatabaseJoin.Log.DatabaseError=A database error occurred, stopping 
everything\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\:
+DatabaseJoin.Log.DatabaseError=A database error occurred, stopping everything\:
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Prelievo dei campi fallito
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Impossibile prelevare i campi 
dai transforms precedenti a causa di un errore
 DatabaseJoin.Exception.FieldNotFound=Il campo richiesto [{0}] non pu\u00F2 
essere trovato\!
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Errore nella ricezione dei 
campi per questo transform
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNumero 
di parametri \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNumero 
di punti di domanda \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNumero 
di parametri \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNumero 
di punti di domanda \=
 DatabaseJoinDialog.Log.GettingKeyInfo=getting key info...
-DatabaseJoin.Log.PutoutRow=Scrivi riga\: 
+DatabaseJoin.Log.PutoutRow=Scrivi riga\:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Tutti i campi sono stati trovati 
nell''input stream.
 DatabaseJoinMeta.DatabaseImpact.Title=Leggi da uno o pi\u00F9 tabelle di 
database tramite statement SQL
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Il transform sta ricevendo 
informazioni dagli altri transforms.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Impossibile leggere i campi 
dal transform precedente.
-DatabaseJoin.Log.LineNumber=line n\u00B0 
+DatabaseJoin.Log.LineNumber=line n\u00B0
 DatabaseJoinMeta.CheckResult.InvalidConnection=Si prega di selezionare o 
creare una connessione\!
 DatabaseJoinDialog.Position.Label=Linea {0} Colonna {1}
-DatabaseJoinMeta.CheckResult.MissingFields=Campi mancanti, non trovati 
nell''input dai precedenti transforms\: 
+DatabaseJoinMeta.CheckResult.MissingFields=Campi mancanti, non trovati 
nell''input dai precedenti transforms\:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Campo parametro
-DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Impossibile 
determinare i campi della query\: 
+DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Impossibile 
determinare i campi della query\:
 DatabaseJoinDialog.Shell.Title=Database Join
 DatabaseJoinDialog.SQL.Label=SQL
-DatabaseJoinDialog.Log.ParametersFound=Trovato 
+DatabaseJoinDialog.Log.ParametersFound=Trovato
 DatabaseJoin.Log.ConnectedToDB=Connesso al database...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERRORE
-DatabaseJoinDialog.Param.Label=Parametri da usare\: 
-DatabaseJoin.Log.ErrorInTransformRunning=A causa di un errore questo transform 
non pu\u00F2 continuare\: 
+DatabaseJoinDialog.Param.Label=Parametri da usare\:
+DatabaseJoin.Log.ErrorInTransformRunning=A causa di un errore questo transform 
non pu\u00F2 continuare\:
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=Numero di 
parametri e numero di placeholders nella query differenti.
 DatabaseJoinMeta.CheckResult.QueryOK=La query \u00E8 specificata funziona 
correttamente.
 DatabaseJoinDialog.Outerjoin.Tooltip=Restituisce almeno la riga d''input ed 
aggiunge NULL per i valori di lookup
 DatabaseJoinMeta.CheckResult.NoInputReceived=Nessun input ricevuto dagli altri 
transforms\!
-DatabaseJoinDialog.Outerjoin.Label=Outer join? 
-DatabaseJoinDialog.TransformName.Label=Nome transform 
+DatabaseJoinDialog.Outerjoin.Label=Outer join?
+DatabaseJoinDialog.TransformName.Label=Nome transform
 DatabaseJoinDialog.ColumnInfo.ParameterType=Tipo
 DatabaseJoin.Log.SQLStatement=Preparare SQL statement\: {0}
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=Numero dei parametri 
corretto. (
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Impossibile verificare la query 
del database\: controlla il log per maggiori informazioni\!
 DatabaseJoinDialog.GetFields.Button=&Preleva i campi
-DatabaseJoin.Log.CheckingRow=Checking row\: 
+DatabaseJoin.Log.CheckingRow=Checking row\:
 DatabaseJoin.Init.ConnectionMissing=Connessione al database mancante per il 
transform [{0}]\!
-DatabaseJoinMeta.CheckResult.DatabaseMetaError=Non \u00E8 possibile recuperare 
un riferimento a databaseMeta per la connessione: ''{0}'' 
\ No newline at end of file
+DatabaseJoinMeta.CheckResult.DatabaseMetaError=Non \u00E8 possibile recuperare 
un riferimento a databaseMeta per la connessione: ''{0}''
+DatabaseJoinDialog.Cache.Label=Abilitare cache?
+DatabaseJoinDialog.CacheSize.Label=Dimensione cache in righe (0\=tutte)
+DatabaseJoinDialog.Injection.Cache=Cache dei dati di lookup?
+DatabaseJoinDialog.Injection.CacheSize=Dimensione cache in righe (0\=tutte)
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ja_JP.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ja_JP.properties
index 3d29f4d61e..de8abbac12 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ja_JP.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ja_JP.properties
@@ -19,26 +19,26 @@
 #
 DatabaseJoin.Name=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u7D50\u5408
 DatabaseJoin.Description=Database 
join\n\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u30B9\u30C8\u30EA\u30FC\u30E0\u5024\u3092\u4F7F\u7528\u3057\u3001\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30AF\u30A8\u30EA\u30FC\u3092\u5B9F\u884C\u3057\u307E\u3059\u3002
-DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\:
 
DatabaseJoinDialog.InvalidConnection.DialogMessage=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 
DatabaseJoinDialog.useVarsjoin.Label=\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B
 
DatabaseJoinDialog.useVarsjoin.Tooltip=\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B\u5834\u5408\u306F\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 DatabaseJoinDialog.Limit.Label=\u6700\u5927\u30EC\u30B3\u30FC\u30C9\u6570
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\: 
-DatabaseJoin.Log.DatabaseError=A database error occurred, stopping 
everything\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\:
+DatabaseJoin.Log.DatabaseError=A database error occurred, stopping everything\:
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=\u30A8\u30E9\u30FC
 
DatabaseJoinDialog.GetFieldsFailed.DialogMessage=\u5148\u884C\u306E\u30B9\u30C6\u30C3\u30D7\u304B\u3089\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3002
 DatabaseJoin.Exception.FieldNotFound=Field [{0}] is required and couldn''t be 
found\!
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Error obtaining fields for 
this transform
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \=
 DatabaseJoinDialog.Log.GettingKeyInfo=getting key info...
-DatabaseJoin.Log.PutoutRow=Put out row\: 
+DatabaseJoin.Log.PutoutRow=Put out row\:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=All fields found in the input 
stream.
 DatabaseJoinMeta.DatabaseImpact.Title=read from one or more database tables 
via SQL statement
 DatabaseJoinMeta.CheckResult.ReceivingInfo=Transform is receiving info from 
other transforms.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Couldn''t read fields from 
the previous transform.
-DatabaseJoin.Log.LineNumber=linenr 
+DatabaseJoin.Log.LineNumber=linenr
 DatabaseJoinMeta.CheckResult.InvalidConnection=Please select or create a 
connection\!
 DatabaseJoinDialog.Position.Label=\u30E9\u30A4\u30F3 {0} \u30AB\u30E9\u30E0 {1}
 DatabaseJoinMeta.CheckResult.MissingFields=Missing fields, not found in input 
from previous transforms\:
@@ -50,7 +50,7 @@ 
DatabaseJoinDialog.Log.ParametersFound=\u898B\u3064\u304B\u308A\u307E\u3057\u305
 
DatabaseJoin.Log.ConnectedToDB=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u63A5\u7D9A\u3055\u308C\u307E\u3057\u305F\u3002...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=\u30A8\u30E9\u30FC
 DatabaseJoinDialog.Param.Label=\u30D1\u30E9\u30E1\u30FC\u30BF
-DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\: 
+DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\:
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=The number 
of parameters and the number of question marks is different.
 DatabaseJoinMeta.CheckResult.QueryOK=The query is specified and working 
correctly.
 
DatabaseJoinDialog.Outerjoin.Tooltip=\u5916\u90E8\u7D50\u5408\u3059\u308B\u5834\u5408\u306F\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
@@ -62,5 +62,7 @@ DatabaseJoin.Log.SQLStatement=Prepare SQL statement \: {0}
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=The number of parameters is 
correct. (
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Couldn''t verify the database 
query\: check the log for more info\!
 DatabaseJoinDialog.GetFields.Button=\ 
\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u53D6\u5F97(&G)
-DatabaseJoin.Log.CheckingRow=Checking row\: 
+DatabaseJoin.Log.CheckingRow=Checking row\:
 DatabaseJoin.Init.ConnectionMissing=Database connection is missing for 
transform [{0}]\!
+DatabaseJoinDialog.Cache.Label=\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u4f7f\u7528
+DatabaseJoinDialog.CacheSize.Label=\u30ad\u30e3\u30c3\u30b7\u30e5\u30b5\u30a4\u30ba
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ko_KR.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ko_KR.properties
index 95ff5d7614..ac419e5263 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ko_KR.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_ko_KR.properties
@@ -27,19 +27,19 @@ 
DatabaseJoin.Log.DatabaseError=\uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uC624\uB958
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=\uD544\uB4DC 
\uAC00\uC838\uC624\uAE30 \uC2E4\uD328
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=\uC624\uB958 
\uB54C\uBB38\uC5D0 \uC774\uC804 transform\uC5D0\uC11C \uD544\uB4DC\uB97C 
\uAC00\uC838\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4
 DatabaseJoin.Exception.FieldNotFound=\uD544\uB4DC [{0}]\uAC00 
\uD544\uC694\uD558\uC9C0\uB9CC \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4\!
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\t\uD30C\uB77C\uBBF8\uD130
 \uAC1C\uC218     \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\t\uBB3C\uC74C\uD45C
 \uAC1C\uC218 \= 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\t\uD30C\uB77C\uBBF8\uD130
 \uAC1C\uC218     \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\t\uBB3C\uC74C\uD45C
 \uAC1C\uC218 \=
 DatabaseJoinDialog.Log.GettingKeyInfo=\uD0A4 \uC815\uBCF4 
\uAC00\uC838\uC624\uAE30...
 DatabaseJoinMeta.CheckResult.AllFieldsFound=\uC785\uB825 
\uC2A4\uD2B8\uB9BC\uC5D0\uC11C \uBAA8\uB4E0 \uD544\uB4DC\uB97C 
\uBC1C\uACAC\uD558\uC600\uC2B5\uB2C8\uB2E4.
 DatabaseJoinMeta.DatabaseImpact.Title=\uD558\uB098 \uB610\uB294 \uADF8 
\uC774\uC0C1\uC758 \uB370\uC774\uD130\uBCA0\uC774\uC2A4 
\uD14C\uC774\uBE14\uC5D0\uC11C SQL \uBB38\uC73C\uB85C \uB370\uC774\uD130 
\uC77D\uAE30
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=\uC774\uC804 
transform\uC5D0\uC11C \uD544\uB4DC\uB97C \uC77D\uC744 \uC218 
\uC5C6\uC2B5\uB2C8\uB2E4.
-DatabaseJoin.Log.LineNumber=\uC904\uBC88\uD638 
+DatabaseJoin.Log.LineNumber=\uC904\uBC88\uD638
 DatabaseJoinMeta.CheckResult.InvalidConnection=\uC5F0\uACB0\uC744 
\uC120\uD0DD\uD558\uAC70\uB098 \uC0DD\uC131\uD558\uC2ED\uC2DC\uC624\!
 DatabaseJoinDialog.Position.Label=Line {0} Column {1}
-DatabaseJoinMeta.CheckResult.MissingFields=\uC774\uC804 transform\uC5D0\uC11C 
\uBC1B\uC740 \uC785\uB825\uC5D0 \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4\: 
+DatabaseJoinMeta.CheckResult.MissingFields=\uC774\uC804 transform\uC5D0\uC11C 
\uBC1B\uC740 \uC785\uB825\uC5D0 \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4\:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=\uD30C\uB77C\uBBF8\uD130 
\uD544\uB4DC\uC774\uB984
 DatabaseJoinDialog.Shell.Title=Database Join
-DatabaseJoinDialog.SQL.Label=SQL 
+DatabaseJoinDialog.SQL.Label=SQL
 DatabaseJoinDialog.Log.ParametersFound=\uBC1C\uACAC
 DatabaseJoin.Log.ConnectedToDB=\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0 
\uC5F0\uACB0...
 DatabaseJoinDialog.InvalidConnection.DialogTitle=\uC624\uB958
@@ -56,3 +56,7 @@ DatabaseJoin.Log.SQLStatement=SQL \uBB38\uC7A5 \uC900\uBE44 
\: {0}
 
DatabaseJoinMeta.CheckResult.InvalidDBQuery=\uB370\uC774\uD130\uBCA0\uC774\uC2A4
 \uCFFC\uB9AC\uB97C \uAC80\uC99D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4\: 
\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 \uB85C\uADF8\uB97C 
\uCC38\uACE0\uD558\uC2ED\uC2DC\uC624\!
 DatabaseJoinDialog.GetFields.Button=\uD544\uB4DC \uAC00\uC838\uC624\uAE30(&G)
 DatabaseJoin.Log.CheckingRow=\uB85C\uD6C4 \uD655\uC778\:
+DatabaseJoinDialog.Cache.Label=\uCE90\uC2DC \uD65C\uC131\uD654?
+DatabaseJoinDialog.CacheSize.Label=\uCE90\uC2DC \uD06C\uAE30 (rows, 0\=cache 
everything)
+DatabaseJoinDialog.Injection.Cache=\uCE90\uC2DC
+DatabaseJoinDialog.Injection.CacheSize=\uCE90\uC2DC \uD06C\uAE30
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_BR.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_BR.properties
index 6b10d1d118..63afad7168 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_BR.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_BR.properties
@@ -18,44 +18,44 @@
 #
 #
 DatabaseJoinDialog.Shell.Title=Jun\u00E7\u00E3o de banco de dados
-DatabaseJoinDialog.TransformName.Label=Nome da transforma\u00E7\u00E3o 
-DatabaseJoinDialog.SQL.Label=SQL 
+DatabaseJoinDialog.TransformName.Label=Nome da transforma\u00E7\u00E3o
+DatabaseJoinDialog.SQL.Label=SQL
 DatabaseJoinDialog.Limit.Label=Numero de linhas para retornar
 DatabaseJoinDialog.Outerjoin.Label=Jun\u00E7\u00E3o externa?
 DatabaseJoinDialog.Outerjoin.Tooltip=Retorna pelo menos a linha de entrada e 
adiciona NULOS para os valores lookup
-DatabaseJoinDialog.GetFields.Button=\ &Obter campos 
-DatabaseJoinDialog.Param.Label==Parâmetros para usar: 
+DatabaseJoinDialog.GetFields.Button=\ &Obter campos
+DatabaseJoinDialog.Param.Label==Parâmetros para usar:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Nome do campo parâmetro
 DatabaseJoinDialog.ColumnInfo.ParameterType=Tipo do Parâmetro
 DatabaseJoinDialog.Log.GettingKeyInfo=obtendo informa\u00E7\u00E3o da chave...
-DatabaseJoinDialog.Log.ParametersFound=Encontrados 
+DatabaseJoinDialog.Log.ParametersFound=Encontrados
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Por favor, selecione uma 
conex\u00E3o v\u00E1lida!
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERRO
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Falha na obten\u00E7\u00E3o dos 
campos
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=N\u00E3o foi poss\u00EDvel 
obter campos de transforma\u00E7\u00F5es anteriores devido a um erro
-DatabaseJoin.Log.CheckingRow=Verificando linha: 
+DatabaseJoin.Log.CheckingRow=Verificando linha:
 DatabaseJoin.Exception.FieldNotFound=Campo [{0}] \u00E9 necess\u00E1rio e 
n\u00E3o foi encontrado !
-DatabaseJoin.Log.PutoutRow=Put out linha: 
-DatabaseJoin.Log.LineNumber=N\u00FAmero da linha 
-DatabaseJoin.Log.ErrorInTransformRunning=Por causa de um erro esta 
transforma\u00E7\u00E3o n\u00E3o pode continuar: 
+DatabaseJoin.Log.PutoutRow=Put out linha:
+DatabaseJoin.Log.LineNumber=N\u00FAmero da linha
+DatabaseJoin.Log.ErrorInTransformRunning=Por causa de um erro esta 
transforma\u00E7\u00E3o n\u00E3o pode continuar:
 DatabaseJoin.Log.ConnectedToDB=Conectado ao banco de dados...
-DatabaseJoin.Log.DatabaseError=Ocorreu um erro de banco de dados, parando 
tudo: 
+DatabaseJoin.Log.DatabaseError=Ocorreu um erro de banco de dados, parando tudo:
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Não possível dterminar 
os campos da consulta:
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Erro obtendo campos para este 
transform
 DatabaseJoinMeta.CheckResult.QueryOK=A consulta está especificada e 
funcionando corretamente.
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Não foi possível verificar a 
consulta ao banco de dados: verifique o log para maiores informações\!
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=O número de 
parâmetros e o número de questões é diferente.
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNúmero 
de questões = 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNúmber 
de parâmetros = 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNúmero 
de questões =
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNúmber 
de parâmetros =
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=O número de parâmetros está 
correto. (
 DatabaseJoinMeta.CheckResult.MissingFields=Campos n\u00E3o encontrados na 
entrada de transforma\u00E7\u00F5es anteriores:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Todos os campos encontrados no 
fluxo de entrada.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=N\u00E3o foi poss\u00EDvel 
ler campos da transforma\u00E7\u00E3o anterior.
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Ocorreu um erro: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Ocorreu um erro:
 DatabaseJoinMeta.CheckResult.InvalidConnection=Por favor, selecione ou crie 
uma conex\u00E3o!
 DatabaseJoinMeta.CheckResult.ReceivingInfo=A transforma\u00E7\u00E3o est\u00E1 
recebendo informa\u00E7\u00F5es de outras transforma\u00E7\u00F5es.
 DatabaseJoinMeta.CheckResult.NoInputReceived=Nenhuma entrada foi recebida de 
outras transforma\u00E7\u00F5es !
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ocorreu um erro de banco de dados: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ocorreu um erro de banco de dados:
 DatabaseJoinMeta.DatabaseImpact.Title=leitura de uma ou mais tabelas de banco 
de dados via comandos SQL
 DatabaseJoin.Init.ConnectionMissing=Conex\u00E3o com banco de dados ausente 
para a transforma\u00E7\u00E3o [{0}] !
 DatabaseJoinMeta.Injection.Parameter.Name=Nome de campo
@@ -67,3 +67,6 @@ DatabaseJoinMeta.keyword=base de dados,bd,jun\u00E7\u00E3o
 DatabaseJoinDialog.useVarsjoin.Label=substituir vari\u00E1veis
 DatabaseJoinMeta.Injection.Parameter.Type=Tipo de campo
 DatabaseJoin.Name=Jun\u00E7\u00E3o de banco de dados
+DatabaseJoinDialog.Cache.Label=Habilita cache?
+DatabaseJoinDialog.CacheSize.Label=Tamanho do cache em linhas (0 = ilimitado)
+
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_PT.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_PT.properties
index d752fc52d6..b199aa91a0 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_PT.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_pt_PT.properties
@@ -18,26 +18,26 @@
 #
 #
 DatabaseJoinDialog.Shell.Title=Junção de banco de dados
-DatabaseJoinDialog.TransformName.Label=Nome do transform 
-DatabaseJoinDialog.SQL.Label=SQL 
+DatabaseJoinDialog.TransformName.Label=Nome do transform
+DatabaseJoinDialog.SQL.Label=SQL
 DatabaseJoinDialog.Limit.Label=Numero de linhas para retornar
 DatabaseJoinDialog.Outerjoin.Label=Outer join?
 DatabaseJoinDialog.Outerjoin.Tooltip=Retorna pelo menos a linha de entrada e 
adiciona NULOS para os valores lookup
-DatabaseJoinDialog.GetFields.Button=\ &Obtem campos 
-DatabaseJoinDialog.Param.Label=Parâmetros para usar: 
+DatabaseJoinDialog.GetFields.Button=\ &Obtem campos
+DatabaseJoinDialog.Param.Label=Parâmetros para usar:
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Nome do campo parâmetro
 DatabaseJoinDialog.ColumnInfo.ParameterType=Tipo do Parâmetro
 DatabaseJoinDialog.Log.GettingKeyInfo=obtendo informação da chave...
-DatabaseJoinDialog.Log.ParametersFound=Encontrados 
+DatabaseJoinDialog.Log.ParametersFound=Encontrados
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Por favor selecione uma 
conexão válida\!
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERRO
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Obtenção de campos falhou
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Não foi possível obter campos 
dos transforms anteriores devido a um erro
-DatabaseJoin.Log.CheckingRow=Verificando linha: 
+DatabaseJoin.Log.CheckingRow=Verificando linha:
 DatabaseJoin.Exception.FieldNotFound=Campo [{0}] é necessário e não foi 
encontrado!
-DatabaseJoin.Log.PutoutRow=Put out linha: 
-DatabaseJoin.Log.LineNumber=linha nr 
-DatabaseJoin.Log.ErrorInTransformRunning=Devido a um erro, este transform não 
pode continuar: 
+DatabaseJoin.Log.PutoutRow=Put out linha:
+DatabaseJoin.Log.LineNumber=linha nr
+DatabaseJoin.Log.ErrorInTransformRunning=Devido a um erro, este transform não 
pode continuar:
 DatabaseJoin.Log.ConnectedToDB=Conectado ao banco de dados...
 DatabaseJoin.Log.DatabaseError=Ocorreu um erro de banco de dados, parando tudo:
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Não possível dterminar 
os campos da consulta:
@@ -45,15 +45,17 @@ DatabaseJoinMeta.Exception.ErrorObtainingFields=Erro 
obtendo campos para este tr
 DatabaseJoinMeta.CheckResult.QueryOK=A consulta está especificada e 
funcionando corretamente.
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Não foi possível verificar a 
consulta ao banco de dados: verifique o log para maiores informações\!
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=O número de 
parâmetros e o número de questões é diferente.
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNúmero 
de questões = 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNúmber 
de parâmetros = 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tNúmero 
de questões =
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tNúmber 
de parâmetros =
 DatabaseJoinMeta.CheckResult.NumberOfParamCorrect=O número de parâmetros está 
correto. (
 DatabaseJoinMeta.CheckResult.MissingFields=Campos não encontrados na entrada 
de transforms anteriores:
 DatabaseJoinMeta.CheckResult.AllFieldsFound=Todos os campos encontrados no 
fluxo de entrada.
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Não foi possível ler os 
campos de transforms anteriores.
-DatabaseJoinMeta.CheckResult.ErrorOccurred=Ocorreu um erro: 
+DatabaseJoinMeta.CheckResult.ErrorOccurred=Ocorreu um erro:
 DatabaseJoinMeta.CheckResult.InvalidConnection=Por favor selecione ou crie uma 
conexão\!
 DatabaseJoinMeta.CheckResult.ReceivingInfo=transform está recenbo informação 
de outros transforms.
 DatabaseJoinMeta.CheckResult.NoInputReceived=Sem entrada recebida de outros 
transforms\!
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ocorreu um erro de banco de dados: 
-DatabaseJoinMeta.DatabaseImpact.Title=leitura de uma ou mais tabelas de banco 
de dados via comandos SQL
\ No newline at end of file
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=Ocorreu um erro de banco de dados:
+DatabaseJoinMeta.DatabaseImpact.Title=leitura de uma ou mais tabelas de banco 
de dados via comandos SQL
+DatabaseJoinDialog.Cache.Label=Habilita cache?
+DatabaseJoinDialog.CacheSize.Label=Tamamho do cache em linhas (0\=todas)
diff --git 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_zh_CN.properties
 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_zh_CN.properties
index 5cf9295bee..337d61be71 100644
--- 
a/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_zh_CN.properties
+++ 
b/plugins/transforms/databasejoin/src/main/resources/org/apache/hop/pipeline/transforms/databasejoin/messages/messages_zh_CN.properties
@@ -19,27 +19,27 @@
 
DatabaseJoin.Description=\u4F7F\u7528\u6570\u636E\u6D41\u91CC\u7684\u503C\u4F5C\u4E3A\u53C2\u6570\u6267\u884C\u4E00\u4E2A\u6570\u636E\u5E93\u67E5\u8BE2
 DatabaseJoin.Exception.FieldNotFound=Field [{0}] is required and couldn''t be 
found\!
 DatabaseJoin.Init.ConnectionMissing=Transform {0} 
\u7F3A\u5931\u6570\u636E\u5E93\u8FDE\u63A5
-DatabaseJoin.Log.CheckingRow=Checking row\: 
+DatabaseJoin.Log.CheckingRow=Checking row\:
 DatabaseJoin.Log.ConnectedToDB=Connected to database...
-DatabaseJoin.Log.DatabaseError=A database error occurred, stopping 
everything\: 
-DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\: 
-DatabaseJoin.Log.LineNumber=linenr 
-DatabaseJoin.Log.PutoutRow=Put out row\: 
+DatabaseJoin.Log.DatabaseError=A database error occurred, stopping everything\:
+DatabaseJoin.Log.ErrorInTransformRunning=Because of an error, this transform 
can''t continue\:
+DatabaseJoin.Log.LineNumber=linenr
+DatabaseJoin.Log.PutoutRow=Put out row\:
 DatabaseJoin.Log.SQLStatement=Prepare SQL Statement\: {0}
 DatabaseJoin.Name=\u6570\u636E\u5E93\u8FDE\u63A5
 DatabaseJoinDialog.ColumnInfo.ParameterFieldname=Parameter fieldname
 DatabaseJoinDialog.ColumnInfo.ParameterType=Parameter Type
-DatabaseJoinDialog.GetFields.Button=\u83B7\u53D6\u5B57\u6BB5 
+DatabaseJoinDialog.GetFields.Button=\u83B7\u53D6\u5B57\u6BB5
 DatabaseJoinDialog.GetFieldsFailed.DialogMessage=Unable to get fields from 
previous transforms because of an error
 DatabaseJoinDialog.GetFieldsFailed.DialogTitle=Get fields failed
 DatabaseJoinDialog.InvalidConnection.DialogMessage=Please select a valid 
connection\!
 DatabaseJoinDialog.InvalidConnection.DialogTitle=ERROR
 DatabaseJoinDialog.Limit.Label=Number of rows to return\:
 DatabaseJoinDialog.Log.GettingKeyInfo=getting key info...
-DatabaseJoinDialog.Log.ParametersFound=Found 
+DatabaseJoinDialog.Log.ParametersFound=Found
 DatabaseJoinDialog.Outerjoin.Label=Outer join\:
 DatabaseJoinDialog.Outerjoin.Tooltip=Return al least the input row and add 
NULLs for the lookup values
-DatabaseJoinDialog.Param.Label=The parameters to use\: 
+DatabaseJoinDialog.Param.Label=The parameters to use\:
 DatabaseJoinDialog.Position.Label=\u884C {0} \u5217 {1}
 DatabaseJoinDialog.SQL.Label=SQL\:
 DatabaseJoinDialog.Shell.Title=Database join
@@ -50,9 +50,9 @@ DatabaseJoinMeta.CheckResult.AllFieldsFound=All fields found 
in the input stream
 DatabaseJoinMeta.CheckResult.CounldNotReadFields=Couldn''t read fields from 
the previous transform.
 
DatabaseJoinMeta.CheckResult.DatabaseMetaError=\u65E0\u6CD5\u4ECE\u6570\u636E\u5E93
 "{0}" \u83B7\u53D6\u5143\u6570\u636E\u4FE1\u606F
 DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion=The number 
of parameters and the number of question marks is different.
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \= 
-DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \= 
-DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\: 
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion2=\t\tThe 
number of question marks \=
+DatabaseJoinMeta.CheckResult.DismatchBetweenParametersAndQuestion3=\t\tThe 
number of parameters     \=
+DatabaseJoinMeta.CheckResult.ErrorOccurred=An error occurred\:
 DatabaseJoinMeta.CheckResult.InvalidConnection=Please select or create a 
connection\!
 DatabaseJoinMeta.CheckResult.InvalidDBQuery=Couldn''t verify the database 
query\: check the log for more info\!
 DatabaseJoinMeta.CheckResult.MissingFields=Missing fields, not found in input 
from previous transforms\:
@@ -63,5 +63,7 @@ DatabaseJoinMeta.CheckResult.ReceivingInfo=Transform is 
receiving info from othe
 DatabaseJoinMeta.DatabaseImpact.Title=read from one or more database tables 
via SQL statement
 DatabaseJoinMeta.Exception.ErrorObtainingFields=Error obtaining fields for 
this transform
 DatabaseJoinMeta.Exception.UnableToDetermineQueryFields=Unable to determine 
the fields of query\:
-DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\: 
+DatabaseJoinMeta.Log.DatabaseErrorOccurred=A database error occurred\:
 DatabaseJoinMeta.keyword=database,db,join
+DatabaseJoinDialog.Cache.Label=\u4F7F\u7528\u7F13\u5B58\:
+DatabaseJoinDialog.CacheSize.Label=\u7F13\u5B58\u5927\u5C0F\:

Reply via email to