diff --git a/.gitlab/issue_templates/Default.md b/.gitlab/issue_templates/Default.md
new file mode 100644
index 0000000000000000000000000000000000000000..aa1a65aca363b87aff50280e1a86824009d2098b
--- /dev/null
+++ b/.gitlab/issue_templates/Default.md
@@ -0,0 +1,28 @@
+## Summary
+
+*Please give a short summary of what the issue is.*
+
+## Expected Behavior
+
+*What did you expect how the software should behave?*
+
+## Actual Behavior
+
+*What did the software actually do?*
+
+## Steps to Reproduce the Problem
+
+*Please describe, step by step, how others can reproduce the problem.  Please try these steps for yourself on a clean system.*
+
+1.
+2.
+3.
+
+## Specifications
+
+- Version: *Which version of this software?*
+- Platform: *Which operating system, which other relevant software versions?*
+
+## Possible fixes
+
+*Do you have ideas how the issue can be resolved?*
diff --git a/.gitlab/merge_request_templates/Default.md b/.gitlab/merge_request_templates/Default.md
new file mode 100644
index 0000000000000000000000000000000000000000..35c6d01c5904289b77fc7f1de9419ef91a1510e9
--- /dev/null
+++ b/.gitlab/merge_request_templates/Default.md
@@ -0,0 +1,54 @@
+# Summary
+
+*Insert a meaningful description for this merge request here:  What is the new/changed behavior?
+Which bug has been fixed? Are there related issues?*
+
+
+# Focus
+
+*Point the reviewer to the core of the code change. Where should they start reading? What should
+they focus on (e.g. security, performance, maintainability, user-friendliness, compliance with the
+specs, finding more corner cases, concrete questions)?*
+
+
+# Test Environment
+
+*How to set up a test environment for manual testing?*
+
+
+# Check List for the Author
+
+Please, prepare your MR for a review. Be sure to write a summary and a focus and create gitlab
+comments for the reviewer. They should guide the reviewer through the changes, explain your changes
+and also point out open questions. For further good practices have a look at [our review
+guidelines](https://gitlab.com/caosdb/caosdb/-/blob/dev/REVIEW_GUIDELINES.md)
+
+- [ ] All automated tests pass
+- [ ] Reference related issues
+- [ ] Up-to-date CHANGELOG.md (or not necessary)
+- [ ] Up-to-date JSON schema (or not necessary)
+- [ ] Appropriate user and developer documentation (or not necessary)
+  - How do I use the software?  Assume "stupid" users.
+  - How do I develop or debug the software?  Assume novice developers.
+- [ ] Annotations in code (Gitlab comments)
+  - Intent of new code
+  - Problems with old code
+  - Why this implementation?
+
+
+# Check List for the Reviewer
+
+- [ ] I understand the intent of this MR
+- [ ] All automated tests pass
+- [ ] Up-to-date CHANGELOG.md (or not necessary)
+- [ ] Appropriate user and developer documentation (or not necessary)
+- [ ] The test environment setup works and the intended behavior is reproducible in the test
+  environment
+- [ ] In-code documentation and comments are up-to-date.
+- [ ] Check: Are there specifications? Are they satisfied?
+
+For further good practices have a look at [our review guidelines](https://gitlab.com/caosdb/caosdb/-/blob/dev/REVIEW_GUIDELINES.md).
+
+
+/assign me
+/target_branch dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7e37c52b9d734da4e877fe6456fb5dee6e02a37..f3c6a023893526d8727858562a87453fdcaed60a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.11.1] - 2023-03-07 ##
+(Florian Spreckelsen)
+
+### Changed ###
+
+* Renamed `caosdb.common.models._Parents` to `caosdb.common.models._ParentList`.
+
+### Fixed ###
+
+* [caosdb-pylib#90](https://gitlab.com/caosdb/caosdb-pylib/-/issues/90): `Entity.get_parents_recursively()` did not work for unretrieved parents.
+
 ## [0.11.0] - 2023-01-19 ##
 (Florian Spreckelsen)
 
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 0000000000000000000000000000000000000000..910e40a2193d527fc8e4eb68c4ca6b10a28d3630
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,25 @@
+cff-version: 1.2.0
+message: "If you use this software, please cite it as below."
+authors:
+  - family-names: Fitschen
+    given-names: Timm
+    orcid: https://orcid.org/0000-0002-4022-432X
+  - family-names: Schlemmer
+    given-names: Alexander
+    orcid: https://orcid.org/0000-0003-4124-9649
+  - family-names: Hornung
+    given-names: Daniel
+    orcid: https://orcid.org/0000-0002-7846-6375
+  - family-names: tom Wörden
+    given-names: Henrik
+    orcid: https://orcid.org/0000-0002-5549-578X
+  - family-names: Parlitz
+    given-names: Ulrich
+    orcid: https://orcid.org/0000-0003-3058-1435
+  - family-names: Luther
+    given-names: Stefan
+    orcid: https://orcid.org/0000-0001-7214-8125
+title: CaosDB - Pylib
+version: 0.11.1
+doi: 10.3390/data4020083
+date-released: 2022-11-14
\ No newline at end of file
diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md
index 863afb8f3ac7d6770c372620523638b900785227..95ee8e314871153476c30790a456242e38dcaf9e 100644
--- a/RELEASE_GUIDELINES.md
+++ b/RELEASE_GUIDELINES.md
@@ -24,6 +24,7 @@ guidelines of the CaosDB Project
    - `version` variables in `src/doc/conf.py`
    - Version on [setup.py](./setup.py): Check the `MAJOR`, `MINOR`, `MICRO`, `PRE` variables and set
      `ISRELEASED` to `True`. Use the possibility to issue pre-release versions for testing.
+   - `CITATION.cff` (update version and date)
 
 5. Merge the release branch into the main branch.
 
diff --git a/setup.py b/setup.py
index 0d2305f0b59453c0d209918fc74b991f87bcbda0..a281a7b67182c19b984846f498bdd99a3a2d6dc5 100755
--- a/setup.py
+++ b/setup.py
@@ -48,7 +48,7 @@ from setuptools import find_packages, setup
 ISRELEASED = True
 MAJOR = 0
 MINOR = 11
-MICRO = 0
+MICRO = 1
 # Do not tag as pre-release until this commit
 # https://github.com/pypa/packaging/pull/515
 # has made it into a release. Probably we should wait for pypa/packaging>=21.4
diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index 83359ac847fa62de976208f9af023a2cf2a73af6..08fcd0206b9df22902e80277d0e57b5f67c76db5 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -34,6 +34,7 @@ All additional classes are either important for the entities or the
 transactions.
 """
 from __future__ import print_function, unicode_literals
+from __future__ import annotations  # Can be removed with 3.10.
 
 import re
 import sys
@@ -82,7 +83,7 @@ SPECIAL_ATTRIBUTES = ["name", "role", "datatype", "description",
                       "id", "path", "checksum", "size"]
 
 
-class Entity(object):
+class Entity:
 
     """Entity is a generic CaosDB object.
 
@@ -101,6 +102,8 @@ class Entity(object):
         self._checksum = None
         self._size = None
         self._upload = None
+        # If an entity is used (e.g. as parent), it is wrapped instead of being used directly.
+        # see Entity._wrap()
         self._wrapped_entity = None
         self._version = None
         self._cuid = None
@@ -111,7 +114,7 @@ class Entity(object):
         self.value = value
         self.messages = _Messages()
         self.properties = _Properties()
-        self.parents = _Parents()
+        self.parents = _ParentList()
         self.path = None
         self.file = None
         self.unit = None
@@ -530,7 +533,7 @@ class Entity(object):
                                 value=value, unit=unit)
 
         if abstract_property is not None:
-            new_property._wrap(property)
+            new_property._wrap(abstract_property)
 
             # FIXME: this really necessary?
 
@@ -621,26 +624,46 @@ class Entity(object):
 
         return self
 
-    def has_parent(self, parent, recursive=True,
-                   check_name=True, check_id=False):
-        """Checks if this entity has a given parent.
+    def has_parent(self, parent: Entity, recursive: bool = True, retrieve: bool = True,
+                   check_name: bool = True, check_id: bool = False):
+        """Check if this entity has a given parent.
 
         If 'check_name' and 'check_id' are both False, test for identity
         on the Python level. Otherwise use the name and/or ID for the
         check. Note that, if checked, name or ID should not be None,
         lest the check fail.
 
-        @param parent: Check for this parent.
-        @param recursive: Whether to check recursively.
-        @param check_name: Whether to use the name for ancestry check.
-        @param check_id: Whether to use the ID for ancestry check.
-        @return: True if 'parent' is a true parent, False otherwise.
-        """
+Parameters
+----------
+
+parent: Entity
+  Check for this parent.
+
+recursive: bool, optional
+  Whether to check recursively.
+
+check_name: bool, optional
+  Whether to use the name for ancestry check.
+
+check_id: bool, optional
+  Whether to use the ID for ancestry check.
+
+retrieve: bool, optional
+  If False, do not retrieve parents from the server.
+
+Returns
+-------
+out: bool
+  True if ``parent`` is a true parent, False otherwise.
+"""
 
         if recursive:
-            parents = self.get_parents_recursively()
+            parents = self.get_parents_recursively(retrieve=retrieve)
         else:
-            parents = [pp._wrapped_entity for pp in self.parents]
+            if retrieve:
+                parents = [pp.retrieve()._wrapped_entity for pp in self.parents]
+            else:
+                parents = [pp._wrapped_entity for pp in self.parents]
 
         if not (check_name or check_id):
             return parent in parents
@@ -659,39 +682,61 @@ class Entity(object):
     def get_parents(self):
         """Get all parents of this entity.
 
-        @return: _Parents(list)
+        @return: _ParentList(list)
         """
 
         return self.parents
 
-    def get_parents_recursively(self):
+    def get_parents_recursively(self, retrieve: bool = True):
         """Get all ancestors of this entity.
 
-        @return: list of Entities
-        """
+Parameters
+----------
+
+retrieve: bool, optional
+  If False, do not retrieve parents from the server.
+
+Returns
+-------
+out: List[Entity]
+  The parents of this Entity
+"""
 
-        all_parents = _Parents()
-        self._get_parent_recursively(all_parents)
+        all_parents = []
+        self._get_parent_recursively(all_parents, retrieve=retrieve)
 
         return all_parents
 
-    def _get_parent_recursively(self, all_parents):
+    def _get_parent_recursively(self, all_parents: list, retrieve: bool = True):
         """Get all ancestors with a little helper.
 
         As a side effect of this method, the ancestors are added to
         all_parents.
 
-        @param all_parents: The added parents so far.
+        @param all_parents: list, The added parents so far.
 
         @return: None, but see side effects.
         """
 
         for parent in self.parents:
+            # TODO:
+            # Comment on _wrap and _wrapped_entity
+            # Currently, I (henrik) do not why the wrapping is necessary (and it is not
+            # documented). However, the following illustrates, why I think, it is a bad idea.
+            # First you add a parent with rec.add_parent(parent), but then you cannot access
+            # attributes of parent when you use rec.parents[0] for example becasue you do not get
+            # the same object but a wrapping object and you need to know that you only get the
+            # original by accessing the private (!) _wrapped_entity object.
             w_parent = parent._wrapped_entity
+            if retrieve:
+                parent.retrieve()
+                for next_parent in parent.parents:
+                    w_parent.add_parent(next_parent)
 
-            if w_parent not in all_parents:
+            if (w_parent.id, w_parent.name) not in [
+                    (all_p.id, all_p.name) for all_p in all_parents]:
                 all_parents.append(w_parent)
-                w_parent._get_parent_recursively(all_parents)
+                w_parent._get_parent_recursively(all_parents, retrieve=retrieve)
 
     def get_parent(self, key):
         """Return the first parent matching the key or None if no match exists.
@@ -1135,7 +1180,7 @@ class Entity(object):
             else:
                 raise TypeError(
                     'Child was neither a Property, nor a Parent, nor a Message.\
-                    Was ' + str(type(child)))
+                    Was ' + str(type(child)) + "\n" + str(child))
 
         # add VALUE
         value = None
@@ -1296,6 +1341,12 @@ class Entity(object):
             flags=flags)[0]
 
     def _wrap(self, entity):
+        """
+        When entity shall be used as parent or property it is not added to the corresponding list
+        (such as the parent list) directly, but another Entity object is created and the original
+        Entity is wrapped using this function
+        TODO: document here and in dev docs why this is done.
+        """
         self._wrapped_entity = entity
 
         return self
@@ -2094,7 +2145,8 @@ class _Properties(list):
         raise KeyError(str(prop) + " not found.")
 
 
-class _Parents(list):
+class _ParentList(list):
+    # TODO unclear why this class is private. Isn't it use full for users?
 
     def _get_entity_by_cuid(self, cuid):
         '''
@@ -2697,9 +2749,11 @@ class Container(list):
         elif isinstance(entity, QueryTemplate):
             super().append(entity)
         else:
-            raise TypeError(
-                "Entity was neither an id nor a name nor an entity." +
-                " (was " + str(type(entity)) + ")")
+            warn("Entity was neither an id nor a name nor an entity." +
+                 " (was " + str(type(entity)) + ":\n" + str(entity) + ")")
+            # raise TypeError(
+            #     "Entity was neither an id nor a name nor an entity." +
+            #     " (was " + str(type(entity)) + "\n" + str(entity) + ")")
 
         return self
 
@@ -3647,6 +3701,7 @@ class Container(list):
             for p in e.get_properties():
                 if p.id is None:
                     if p.name is not None:
+                        # TODO using try except for normal execution flow is bad style
                         try:
                             w = self.get_entity_by_name(p.name)
                             p._wrap(w)
@@ -3658,6 +3713,7 @@ class Container(list):
             for p in e.get_parents():
                 if p.id is None:
                     if p.name is not None:
+                        # TODO using try except for normal execution flow is bad style
                         try:
                             p._wrap(self.get_entity_by_name(p.name))
                         except KeyError:
diff --git a/src/caosdb/connection/connection.py b/src/caosdb/connection/connection.py
index a2802848af7bae8fb65378532156d8469f31a9b8..46dadea9dfcfa6e614493b75d709f604aa188ef6 100644
--- a/src/caosdb/connection/connection.py
+++ b/src/caosdb/connection/connection.py
@@ -287,6 +287,8 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
                             "Insecure SSL mode, certificate will not be checked! "
                             "Please consider removing the `ssl_insecure` configuration option.\n"
                             "****************")
+            warnings.filterwarnings(action="ignore", module="urllib3",
+                                    message="Unverified HTTPS request is being made")
             verify = False
         if verify is not None:
             self._session.verify = verify
diff --git a/src/doc/conf.py b/src/doc/conf.py
index b6d82cd82ee62e6a03c2fdea8c35129adb6096a9..3168916a86d208417ce580d43ce8ae952dde930d 100644
--- a/src/doc/conf.py
+++ b/src/doc/conf.py
@@ -29,10 +29,10 @@ copyright = '2022, IndiScale GmbH'
 author = 'Daniel Hornung'
 
 # The short X.Y version
-version = '0.11.0'
+version = '0.11.1'
 # The full version, including alpha/beta/rc tags
 # release = '0.5.2-rc2'
-release = '0.10.1'
+release = '0.11.1'
 
 
 # -- General configuration ---------------------------------------------------