如何对软件包、版本和许可证进行建模



我现在有点卡住了。问题是关于npm软件包、它们的版本/发布以及它们的许可证。

这是一个简单的许可

CREATE TABLE IF NOT EXISTS license (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
reference TEXT NOT NULL,
is_deprecated_license_id BOOLEAN NOT NULL,
reference_number INTEGER NOT NULL,
license_id TEXT NOT NULL,
is_osi_approved BOOLEAN NOT NULL
);
INSERT INTO license
("name",reference,is_deprecated_license_id,reference_number,license_id,is_osi_approved)
VALUES
('Academic Free License v2.0','./AFL-2.0.json',false,0,'AFL-2.0',true);

这是我的包裹

CREATE TABLE IF NOT EXISTS npm_package (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL
);
INSERT INTO npm_package 
(name, description)
VALUES
('react', 'React is a JavaScript library for building user interfaces.'),
('react-router-dom', 'DOM bindings for React Router'),
('typescript', 'TypeScript is a language for application scale JavaScript development'),
('react-dom', 'React package for working with the DOM.');

一个软件包有多个版本,每个版本都有许可证,例如

  • react-1.0.0-MIT
  • react-2.0.0-BSD
  • 反应-3.0.0-MIT

版本只是一个semver字符串。

CREATE TABLE IF NOT EXISTS npm_version (
npm_package_id BIGINT NOT NULL REFERENCES npm_package,
version TEXT NOT NULL,
license_id INTEGER NOT NULL REFERENCES license
)

现在,我正尝试用SpringBoot和Hibernate对此进行建模。这是我迄今为止得到的。

@Entity
public class License {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String reference;
private Boolean isDeprecatedLicenseId;
private Integer referenceNumber;
private String name;
private String licenseId;
private Boolean isOsiApproved;
}

这是我的npm包。

@Entity
public class NpmPackage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
}

现在我想合并软件包、它们的版本和许可证。如何使用Hibernate?我要查找的查询类似于";给我所有"react"的版本,并获得相应的许可证";

非常感谢!


编辑2021年3月24日

我做了更多的研究,取得了更大的进展。让我们暂时删除许可证、焦点、软件包和版本。

以下是我创建包的方法。

CREATE TABLE IF NOT EXISTS npm_package (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL
);
INSERT INTO npm_package 
(name, description)
VALUES
('react', 'React is a JavaScript library for building user interfaces.'),
('react-router-dom', 'DOM bindings for React Router'),
('typescript', 'TypeScript is a language for application scale JavaScript development'),
('react-dom', 'React package for working with the DOM.');

以下是我创建版本的方法。一个版本不应该需要额外的标识符。包和版本的组合是独一无二的。

CREATE TABLE IF NOT EXISTS npm_package_version (
npm_package_id BIGINT NOT NULL REFERENCES npm_package,
version TEXT NOT NULL,
UNIQUE(npm_package_id, version)
)

这是NpmPackage.java

@Entity
public class NpmPackage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany
private List<NpmPackageVersion> versions;
private String name;
private String description;
}

这是NpmPackageVersion.java

@Entity
public class NpmPackageVersion {
@EmbeddedId
private NpmPackageIdVersion npmPackageIdVersion;
@MapsId("npmPackageId")
@ManyToOne
private NpmPackage npmPackage;
@Embeddable
public class NpmPackageIdVersion implements Serializable {
private static final long serialVersionUID = 3357194191099820556L;
private Long npmPackageId;
private String version;
}
}

没有@MapsId,我得到了

表[npm_package_version]包含多个逻辑列名所引用的物理列名[npm-package_id]:[npm_paackage_id]、[npmPackageId]

使用@MapsId,我获得

架构验证:表[npm_package_versions]中缺少列[versions_npm_package _id]

当我将列重命名为versions_npm_package_id时,我得到

架构验证:表[npm_package_versions]中缺少列[npm_paackage_id]

我在兜圈子,哪儿也跑不动。好久没有这么愚蠢了。我还在等";点击";每当我开始使用新技术时,都会举办活动。不幸的是,这还没有发生:(

有什么想法吗?

您非常接近于找到解决方案。

以下设置有效:

NpmPackage

@Entity
@Table(name = "npm_package")
public class NpmPackage {
public NpmPackage(String name, String description) {
this.name = name;
this.description = description;
}
public NpmPackage() {
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@OneToMany(mappedBy = "npmPackage", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<NpmPackageVersion> versions = new ArrayList<>();
...//getters and setters
public void addVersion(NpmPackageVersion version) {
this.versions.add(version);
version.setNpmPackage(this);
}
public void removeVersion(NpmPackageVersion version) {
this.versions.remove(version);
}
}

NpmPackageVersion

@Entity
@Table(name = "npm_package_version")
public class NpmPackageVersion {
public NpmPackageVersion(String version, License license) {
setVersion(version);
this.license = license;
}
public NpmPackageVersion() {
}
@EmbeddedId
private NpmPackageIdVersion npmPackageIdVersion = new NpmPackageIdVersion();
@MapsId("npmPackageId")
@ManyToOne
private NpmPackage npmPackage;
@ManyToOne
private License license;
public String getVersion() {
return npmPackageIdVersion.version;
}
public void setVersion(String version) {
npmPackageIdVersion.version = version;
}
...//getters and setters
@Embeddable
public static class NpmPackageIdVersion implements Serializable {
private static final long serialVersionUID = 3357194191099820556L;
private Long npmPackageId;
private String version;
... //getters and setters etc.
}
}

许可证

@Entity
@Table(name = "license")
public class License {
public License() {}
public License(String name, String licenseId) {
this.name = name;
this.licenseId = licenseId;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String reference;
@Column(name = "is_deprecated_license_id")
private boolean deprecatedLicenseId;
private Integer referenceNumber;
private String name;
private String licenseId;
@Column(name = "is_osi_approved")
private boolean osiApproved;
... //getters and setters
}

我使用以下代码来测试它:

@Transactional
public NpmPackage createPackage() {
License license = new License("General Public License", "GPL 2.0");
em.persist(license);
NpmPackage npmPackage = new NpmPackage("react", "React Framework");
npmPackage.addVersion(new NpmPackageVersion("8.11.0", license));
em.persist(npmPackage);
}

最新更新