diff --git a/serial.services.yml b/serial.services.yml
index 7024aab..792e897 100644
--- a/serial.services.yml
+++ b/serial.services.yml
@@ -1,4 +1,4 @@
 services:
   serial.sql_storage:
     class:  Drupal\serial\SerialSQLStorage
-    arguments: ['@entity.query', '@entity_type.manager']
+    arguments: ['@entity.query', '@entity_type.manager', '@database']
diff --git a/src/Plugin/Field/FieldWidget/SerialDisabledWidget.php b/src/Plugin/Field/FieldWidget/SerialDisabledWidget.php
new file mode 100644
index 0000000..9173a67
--- /dev/null
+++ b/src/Plugin/Field/FieldWidget/SerialDisabledWidget.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\serial\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\serial\Plugin\Field\FieldType\SerialItem;
+
+/**
+ * Plugin implementation of the 'serial_disabled' widget.
+ *
+ * @FieldWidget(
+ *   id = "serial_disabled_widget",
+ *   label = @Translation("Disabled (Automatic)"),
+ *   field_types = {
+ *     "serial"
+ *   }
+ * )
+ */
+class SerialDisabledWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $item = $items[$delta];
+
+    $serial_value = $this->getSerialValue($item);
+
+    $element['value'] = $element + [
+      '#type' => 'textfield',
+
+      // Default value cannot be NULL,
+      // throws 'This value should be of the correct primitive type'.
+      // @see https://www.drupal.org/node/2220381
+      // so the serial is defaulted to a positive int.
+      '#default_value' => $serial_value,
+    ];
+    $element['#disabled'] = TRUE;
+    $element['#description'] = $this->t('Given value might be higher if other entities with this field are made in the meantime.');
+
+    return $element;
+  }
+
+  public function getSerialValue(SerialItem $item) {
+    $entity = $item->getEntity();
+    if ($entity->isNew() && empty($item->value)) {
+      $serialStorage = \Drupal::getContainer()->get('serial.sql_storage');
+
+      if ($currentValue = $serialStorage->getNextValue($item->getFieldDefinition(), $entity)) {
+        return $currentValue;
+      }
+    }
+    return (!empty($item->value) ? $item->value : 0);
+  }
+}
diff --git a/src/SerialSQLStorage.php b/src/SerialSQLStorage.php
index 1f7e12f..90d8168 100644
--- a/src/SerialSQLStorage.php
+++ b/src/SerialSQLStorage.php
@@ -9,6 +9,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Entity\EntityTypeManager;
 use Drupal\Core\Entity\Query\QueryFactory;
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\Condition;

 /**
  * Serial storage service definition.
@@ -34,12 +36,21 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
   protected $entityTypeManager;

   /**
+   * Drupal\Core\Database\Connection definition
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $database;
+
+  /**
    * {@inheritdoc}
    */
   public function __construct(QueryFactory $entityQuery,
-                              EntityTypeManager $entityTypeManager) {
+                              EntityTypeManager $entityTypeManager,
+                              Connection $database) {
     $this->entityQuery = $entityQuery;
     $this->entityTypeManager = $entityTypeManager;
+    $this->database = $database;
   }

   /**
@@ -48,7 +59,8 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.query'),
-      $container->get('entity_type.manager')
+      $container->get('entity_type.manager'),
+      $container->get('database')
     );
   }

@@ -67,33 +79,34 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
    * {@inheritdoc}
    */
   public function createStorageName($entityTypeId, $entityBundle, $fieldName) {
-    // Remember about max length of MySQL tables - 64 symbols.
+    // To make sure we don't end up with table names longer than 64 characters,
+    // which is a MySQL limit we hash a combination of fields.
     // @todo Think about improvement for this.
     $tableName = 'serial_' . md5("{$entityTypeId}_{$entityBundle}_{$fieldName}");
-    return Database::getConnection()->escapeTable($tableName);
+    return $this->database->escapeTable($tableName);
   }

   /**
    * {@inheritdoc}
    */
   public function generateValueFromName($storageName, $delete = TRUE) {
-    $connection = Database::getConnection();
     // @todo review https://api.drupal.org/api/drupal/core%21includes%21database.inc/function/db_transaction/8.2.x
-    $transaction = $connection->startTransaction();
+    $transaction = $this->database->startTransaction();

     try {
       // Insert a temporary record to get a new unique serial value.
       $uniqid = uniqid('', TRUE);
-      $sid = $connection->insert($storageName)
+      $sid = $this->database->insert($storageName)
         ->fields(array('uniqid' => $uniqid))
         ->execute();

       // If there's a reason why it's come back undefined, reset it.
       $sid = isset($sid) ? $sid : 0;

-      // Delete the temporary record.
+      // Only keep 10 rows in the database.
+      // Prevents a huge table and deletion isn't required everytime.
       if ($delete && $sid && ($sid % 10) == 0) {
-        $connection->delete($storageName)
+        $this->database->delete($storageName)
           ->condition('sid', $sid, '<')
           ->execute();
       }
@@ -123,6 +136,29 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
   /**
    * {@inheritdoc}
    */
+  public function getNextValue(FieldDefinitionInterface $fieldDefinition, FieldableEntityInterface $entity) {
+    $storageName = $this->createStorageNameFromField($fieldDefinition, $entity);
+
+    $schema = $this->database->schema();
+    $table_name = $schema->prefixNonTable($storageName);
+
+    $info = $this->database->getConnectionOptions();
+    $database_name = $info['database'];
+
+    $condition = new Condition('AND');
+    $condition->condition('table_name', $table_name);
+    $condition->condition('table_schema', $database_name);
+    $condition->compile($this->database, $schema);
+
+    if ($value = $this->database->query("SELECT auto_increment FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments())->fetchColumn()) {
+      return $value;
+    }
+    return 0;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getSchema() {
     $schema = array(
       'fields' => array(
@@ -172,7 +208,7 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
    * {@inheritdoc}
    */
   public function createStorageFromName($storageName) {
-    $dbSchema = Database::getConnection()->schema();
+    $dbSchema = $this->database->schema();
     if (!$dbSchema->tableExists($storageName)) {
       $dbSchema->createTable($storageName, $this->getSchema());
     }
@@ -189,7 +225,7 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
    * {@inheritdoc}
    */
   public function dropStorageFromName($storageName) {
-    $dbSchema = Database::getConnection()->schema();
+    $dbSchema = $this->database->schema();
     $dbSchema->dropTable($storageName);
   }

@@ -201,6 +237,7 @@ class SerialSQLStorage implements ContainerInjectionInterface, SerialStorageInte
     // @todo shall we assign serial id to unpublished as well?
     // $query->condition('status', 1);
     $query->condition('type', $entityBundle);
     $entityIds = $query->execute();

     $updated = 0;
diff --git a/src/Tests/SerialFieldTest.php b/src/Tests/SerialFieldTest.php
index fdb9f1f..fdc5211 100644
--- a/src/Tests/SerialFieldTest.php
+++ b/src/Tests/SerialFieldTest.php
@@ -53,6 +53,7 @@ class SerialFieldTest extends WebTestBase {
       'entity_type' => 'node',
       'type' => 'serial',
     ))->save();
     FieldConfig::create([
       'field_name' => 'field_serial',
       'label' => 'Serial ID',
@@ -60,21 +61,19 @@ class SerialFieldTest extends WebTestBase {
       'bundle' => 'article',
     ])->save();

-    // @todo review deprecated
-    entity_get_form_display('node', 'article', 'default')
-      ->setComponent('field_serial', array(
-        'type' => 'serial_default_widget',
-        'settings' => array(),
-      ))
-      ->save();
-
-    // @todo review deprecated
-    entity_get_display('node', 'article', 'default')
-      ->setComponent('field_serial', array(
-        'type' => 'serial_default_formatter',
-        'weight' => 1,
-      ))
-      ->save();
+    $entity_form_display_storage = \Drupal::entityTypeManager()->getStorage('entity_form_display');
+    $entity_form_display = $entity_form_display_storage->load('node.article.default');
+    $entity_form_display->setComponent('field_serial', [
+      'type' => 'serial_default_widget',
+      'settings' => [],
+    ])->save();
+
+    $entity_view_display_storage = \Drupal::entityTypeManager()->getStorage('entity_view_display');
+    $entity_view_display = $entity_view_display_storage->load('node.article.default');
+    $entity_view_display->setComponent('field_serial', [
+      'type' => 'serial_default_formatter',
+      'weight' => 1,
+    ])->save();

     // @todo implement logic from SerialTestCase
     // Display creation form.
@@ -86,6 +85,22 @@ class SerialFieldTest extends WebTestBase {

     $this->drupalPostForm('node/add/article', $edit, t('Save'));
     $this->assertRaw('1', 'Serial id ok');
+
+    $entity_form_display->setComponent('field_serial', [
+      'type' => 'serial_disabled_widget',
+      'settings' => [],
+    ])->save();
+
+    // @todo implement logic from SerialTestCase
+    // Display creation form.
+    $this->drupalGet('node/add/article');
+    $this->assertFieldByName("field_serial[0][value]", '2', 'Disabled widget value found.');
+
+    // Test basic entry of serial field.
+    $edit = array();
+
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
+    $this->assertRaw('2', 'Serial id ok');
   }

 }
